# Runs `ethereum/hive` tests.

name: hive

on:
  workflow_dispatch:
  schedule:
    # every day
    - cron: "0 0 * * *"

env:
  CARGO_TERM_COLOR: always

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

jobs:
  prepare-reth:
    if: github.repository == 'paradigmxyz/reth'
    timeout-minutes: 45
    runs-on:
      group: Reth
    steps:
      - uses: actions/checkout@v4
      - run: mkdir artifacts 
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
        with:
          cache-on-failure: true
      - name: Build reth
        run: |
          cargo build --features asm-keccak --profile hivetests --bin reth --locked
          mkdir dist && cp ./target/hivetests/reth ./dist/reth
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Build and export reth image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: .github/assets/hive/Dockerfile
          tags: ghcr.io/paradigmxyz/reth:latest
          outputs: type=docker,dest=./artifacts/reth_image.tar
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Upload reth image
        uses: actions/upload-artifact@v4
        with:
          name: artifacts
          path: ./artifacts

  prepare-hive:
    if: github.repository == 'paradigmxyz/reth'
    timeout-minutes: 45
    runs-on:
      group: Reth
    steps:
      - uses: actions/checkout@v4
      - name: Checkout hive tests
        uses: actions/checkout@v4
        with:
          repository: ethereum/hive
          ref: master
          path: hivetests

      - uses: actions/setup-go@v5
        with:
          go-version: "^1.13.1"
      - run: go version

      - name: Build hive assets
        run: .github/assets/hive/build_simulators.sh

      - name: Upload hive assets
        uses: actions/upload-artifact@v4
        with:
          name: hive_assets
          path: ./hive_assets
  test:
    timeout-minutes: 60
    strategy:
      fail-fast: false
      matrix:
        # ethereum/rpc to be deprecated:
        # https://github.com/ethereum/hive/pull/1117
        sim: [smoke/genesis, smoke/network, ethereum/sync]
        include:
          - sim: devp2p
            limit: discv4
          - sim: devp2p
            limit: eth
            include:
              # status
              - TestStatus
              # get block headers
              - TestGetBlockHeaders
              - TestSimultaneousRequests
              - TestSameRequestID
              - TestZeroRequestID
              # get block bodies
              - TestGetBlockBodies
              # malicious handshakes + status
              - TestMaliciousHandshake
              - TestMaliciousStatus
              # test transactions
              - TestLargeTxRequest
              - TestTransaction
              - TestInvalidTxs
              - TestNewPooledTxs
              - TestBlobViolations
          - sim: ethereum/engine
            limit: engine-exchange-capabilities
          - sim: ethereum/engine
            limit: engine-withdrawals
          - sim: ethereum/engine
            limit: engine-auth
          - sim: ethereum/engine
            limit: engine-api
          - sim: ethereum/engine
            limit: cancun
          # eth_ rpc methods
          - sim: ethereum/rpc-compat
            include:
              - eth_blockNumber
              - eth_call
              - eth_chainId
              - eth_createAccessList
              - eth_estimateGas
              - eth_feeHistory
              - eth_getBalance
              - eth_getBlockBy
              - eth_getBlockTransactionCountBy
              - eth_getCode
              - eth_getProof
              - eth_getStorage
              - eth_getTransactionBy
              - eth_getTransactionCount
              - eth_getTransactionReceipt
              - eth_sendRawTransaction
              - eth_syncing
          # debug_ rpc methods
          - sim: ethereum/rpc-compat
            include: [debug_]
          # Pyspec cancun jobs
          - sim: pyspec
            include: [cancun/eip4844]
          - sim: pyspec
            include: [cancun/eip4788]
          - sim: pyspec
            include: [cancun/eip6780]
          - sim: pyspec
            include: [cancun/eip5656]
          - sim: pyspec
            include: [cancun/eip1153]
          - sim: pyspec
            include: [cancun/eip7516]
          # Pyspec shanghai jobs
          - sim: pyspec
            include: [shanghai/eip3651]
          - sim: pyspec
            include: [shanghai/eip3855]
          - sim: pyspec
            include: [shanghai/eip3860]
          - sim: pyspec
            include: [shanghai/eip4895]
          # Pyspec merge and earlier jobs
          - sim: pyspec
            include: [merge/]
          - sim: pyspec
            include: [berlin/]
          - sim: pyspec
            include: [istanbul/]
          - sim: pyspec
            include: [homestead/]
          - sim: pyspec
            include: [frontier/]
    needs: 
      - prepare-reth
      - prepare-hive
    name: run
    runs-on:
      group: Reth
    permissions:
      issues: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Download hive assets
        uses: actions/download-artifact@v4
        with:
          name: hive_assets
          path: /tmp

      - name: Download reth image
        uses: actions/download-artifact@v4
        with:
          name: artifacts
          path: /tmp

      - name: Load Docker images
        run: .github/assets/hive/load_images.sh

      - name: Move hive binary
        run: |
          mv /tmp/hive /usr/local/bin
          chmod +x /usr/local/bin/hive

      - name: Checkout hive tests
        uses: actions/checkout@v4
        with:
          repository: ethereum/hive
          ref: master
          path: hivetests

      - name: Run ${{ matrix.sim }} simulator
        run: .github/assets/hive/run_simulator.sh "${{ matrix.sim }}$" "${{matrix.limit}}/${{join(matrix.include, '|')}}"

      - name: Parse hive output
        run: |
          find hivetests/workspace/logs -type f -name "*.json" ! -name "hive.json" | xargs -I {} python .github/assets/hive/parse.py {} --exclusion .github/assets/hive/expected_failures.yaml

      - name: Print simulator output
        if: ${{ failure() }}
        run: |
          cat hivetests/workspace/logs/*simulator*.log

      - name: Print reth client logs
        if: ${{ failure() }}
        run: |
          cat hivetests/workspace/logs/reth/client-*.log
  notify-on-error:
    needs: test
    if: failure()
    runs-on:
      group: Reth
    steps:
      - name: Discord Webhook Action
        uses: tsickert/discord-webhook@v6.0.0
        with:
          webhook-url: ${{ secrets.RETH_ALERTS_WEBHOOK }}
          content: "Failed run: https://github.com/paradigmxyz/reth/actions/runs/${{ github.run_id }}"
