From 7ca56bf5c1492d84da2a47ae45d6abae10354449 Mon Sep 17 00:00:00 2001 From: SamAg19 Date: Sun, 26 Jul 2026 00:12:30 +0530 Subject: [PATCH 1/9] add hive binary build target with ref-based caching --- .gitignore | 1 + lean_client/Makefile | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/.gitignore b/.gitignore index 0ed8991..96635e6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ lean_client/target/* lean_client/tests/mainnet lean_client/bin lean_client/spec/ +lean_client/hive/ target/* *.local* diff --git a/lean_client/Makefile b/lean_client/Makefile index b363be3..82cf304 100644 --- a/lean_client/Makefile +++ b/lean_client/Makefile @@ -126,6 +126,31 @@ docker-local: ./target/x86_64-unknown-linux-gnu/release/lean_client $(DOCKER_TAGS) \ . +### Hive +# ethereum/hive ref to build. Unset (default) => latest master, resolved at +# clone time. Override with `make test-hive HIVE_VERSION=` to pin. +HIVE_VERSION ?= +HIVE_REF := $(or $(HIVE_VERSION),master) + +# The hive binary is a real-file target so Make caches it. It depends on a +# ref stamp: changing HIVE_VERSION changes the stamp filename, which forces a +# fresh clone + rebuild; an unchanged ref leaves the binary untouched. +hive/hive: hive/.hive-ref-$(HIVE_REF) + @echo "==> Building hive binary (go build)..." + @cd hive && go build . + @echo "==> Built hive binary at hive/hive ($$(cd hive && git rev-parse --short HEAD))" + +hive/.hive-ref-$(HIVE_REF): + @echo "==> Fetching ethereum/hive at ref '$(HIVE_REF)'..." + @rm -rf hive + @mkdir -p hive + @cd hive && git init -q && \ + git remote add origin https://github.com/ethereum/hive.git && \ + git fetch --depth 1 -q origin $(HIVE_REF) && \ + git switch -q --detach FETCH_HEAD + @echo "==> Checked out hive at $$(cd hive && git rev-parse --short HEAD)" + @touch $@ + ### Shadow-simulator support # `rust/patch/quinn-udp` is a vendored fallback-only build of quinn-udp so QUIC # runs under the Shadow simulator (which does not emulate sendmsg cmsg / GRO / From 5ae5fc87e70f3bfaa44d5f01e8b9cd3da380b297 Mon Sep 17 00:00:00 2001 From: SamAg19 Date: Sun, 26 Jul 2026 15:07:21 +0530 Subject: [PATCH 2/9] add test-hive to Makefile and enable local rebuild on source code changes --- Makefile | 4 ++++ lean_client/Makefile | 22 +++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index d000b1c..908ff7c 100644 --- a/Makefile +++ b/Makefile @@ -32,3 +32,7 @@ docker-local: .PHONY: release release: $(MAKE) -C lean_client release + +.PHONY: test-hive +test-hive: + $(MAKE) -C lean_client test-hive diff --git a/lean_client/Makefile b/lean_client/Makefile index 82cf304..16ec471 100644 --- a/lean_client/Makefile +++ b/lean_client/Makefile @@ -81,18 +81,23 @@ build: clean: cargo clean rm -rf ./bin + rm -rf ./hive + +CLIENT_SOURCES := $(shell find . \( -name '*.rs' -o -name 'Cargo.toml' \) \ + -not -path './target/*' -not -path './hive/*' -not -path './spec/*' \ + -not -path './bin/*') Cargo.lock .PHONY: x86_64-unknown-linux-gnu x86_64-unknown-linux-gnu: ./target/x86_64-unknown-linux-gnu/release/lean_client -./target/x86_64-unknown-linux-gnu/release/lean_client: +./target/x86_64-unknown-linux-gnu/release/lean_client: $(CLIENT_SOURCES) CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C target-cpu=x86-64-v3" \ LEAN_REPO_ROOT=$(LEAN_REPO_ROOT) cross build --bin lean_client --target x86_64-unknown-linux-gnu --profile release .PHONY: aarch64-unknown-linux-gnu aarch64-unknown-linux-gnu: ./target/aarch64-unknown-linux-gnu/release/lean_client -./target/aarch64-unknown-linux-gnu/release/lean_client: +./target/aarch64-unknown-linux-gnu/release/lean_client: $(CLIENT_SOURCES) LEAN_REPO_ROOT=$(LEAN_REPO_ROOT) cross build --bin lean_client --target aarch64-unknown-linux-gnu --profile release .PHONY: release @@ -132,9 +137,16 @@ docker-local: ./target/x86_64-unknown-linux-gnu/release/lean_client HIVE_VERSION ?= HIVE_REF := $(or $(HIVE_VERSION),master) -# The hive binary is a real-file target so Make caches it. It depends on a -# ref stamp: changing HIVE_VERSION changes the stamp filename, which forces a -# fresh clone + rebuild; an unchanged ref leaves the binary untouched. +.PHONY: test-hive +test-hive: hive/hive docker-local + cd hive && ./hive --sim lean \ + --client-file simulators/lean/clients/devnet5.yaml \ + --client grandine_lean_devnet5 \ + --sim.limit 'lean-spec-tests-verify-signatures' \ + --docker.output \ + --docker.nocache="hive/clients/grandine_lean_devnet5" \ + --results-root ./workspace/logs + hive/hive: hive/.hive-ref-$(HIVE_REF) @echo "==> Building hive binary (go build)..." @cd hive && go build . From f403475fc3ccb619fb8e48ad6b431bbf09646cd2 Mon Sep 17 00:00:00 2001 From: SamAg19 Date: Sun, 26 Jul 2026 15:24:59 +0530 Subject: [PATCH 3/9] add hive CI workflow to run test-hive on pull requests --- .github/workflows/hive.yaml | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .github/workflows/hive.yaml diff --git a/.github/workflows/hive.yaml b/.github/workflows/hive.yaml new file mode 100644 index 0000000..c55136b --- /dev/null +++ b/.github/workflows/hive.yaml @@ -0,0 +1,45 @@ +name: Hive + +# For now this runs on every pull request (plus manual dispatch) so we can +# confirm the pipeline works on CI. Once verified, gate it behind a `run-hive` +# label to avoid running the slow suite on every push. +on: + - pull_request + - workflow_dispatch + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + hive: + name: Run hive tests + runs-on: ubuntu-latest + # hive itself imposes no timeout; cap the job so a hang can't run forever. + timeout-minutes: 90 + env: + # `docker-local` -> `cross` bind-mounts this into the build container. + LEAN_REPO_ROOT: ${{ github.workspace }} + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + submodules: recursive + + # Needed to build the hive binary (`go build .`). + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: stable + + # Needed by `docker-local` to cross-build the x86_64 client binary. + - name: Install cross + run: cargo install cross --git https://github.com/cross-rs/cross --rev 7b24b6e9f6834a3ac31d3dad1e2ff24c1b66f7cf + + # hive launches client containers; restart docker to settle iptables + # rules on the runner (same workaround the zeam hive workflow uses). + - name: Restart docker + run: sudo systemctl restart docker + + - name: Run hive tests + run: make test-hive From c3d3026cc1ce67e54876dc7169476e1ea44c10f3 Mon Sep 17 00:00:00 2001 From: SamAg19 Date: Sun, 26 Jul 2026 16:07:25 +0530 Subject: [PATCH 4/9] add hive testing section to README and disable unused go cache in CI --- .github/workflows/hive.yaml | 1 + README.md | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/.github/workflows/hive.yaml b/.github/workflows/hive.yaml index c55136b..f5a8f33 100644 --- a/.github/workflows/hive.yaml +++ b/.github/workflows/hive.yaml @@ -31,6 +31,7 @@ jobs: uses: actions/setup-go@v5 with: go-version: stable + cache: false # Needed by `docker-local` to cross-build the x86_64 client binary. - name: Install cross diff --git a/README.md b/README.md index 5546c2c..688a852 100644 --- a/README.md +++ b/README.md @@ -71,3 +71,27 @@ leanEthereum Consensus Client written in Rust using Grandine's libraries. ``` After a minute all the nodes should be synced up and see each other + +## Running Hive tests + +Runs the [Hive](https://github.com/ethereum/hive) lean simulator against our +`grandine_lean` client. From the repo root: + +```bash +make test-hive +``` + +Requires a **Go toolchain**, **Docker** (running, usable without `sudo`), and +**Rust + [`cross`](https://github.com/cross-rs/cross)**. + +Pin a hive version (defaults to latest `master`): + +```bash +make test-hive HIVE_VERSION= +``` + +Remove the hive clone and other build artifacts: + +```bash +make clean +``` From 42c2ed66312c1dc73a434ff3abc7331dababd2d1 Mon Sep 17 00:00:00 2001 From: SamAg19 Date: Sun, 26 Jul 2026 16:18:09 +0530 Subject: [PATCH 5/9] Run all hive tests on grandine --- lean_client/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/lean_client/Makefile b/lean_client/Makefile index 16ec471..37f90c9 100644 --- a/lean_client/Makefile +++ b/lean_client/Makefile @@ -142,7 +142,6 @@ test-hive: hive/hive docker-local cd hive && ./hive --sim lean \ --client-file simulators/lean/clients/devnet5.yaml \ --client grandine_lean_devnet5 \ - --sim.limit 'lean-spec-tests-verify-signatures' \ --docker.output \ --docker.nocache="hive/clients/grandine_lean_devnet5" \ --results-root ./workspace/logs From e9e8a2a2991ccf9333f5336e0c10ea61f777c9e1 Mon Sep 17 00:00:00 2001 From: Sameer Agarwal Date: Sun, 26 Jul 2026 19:26:22 +0530 Subject: [PATCH 6/9] Increase Hive CI timeout --- .github/workflows/hive.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hive.yaml b/.github/workflows/hive.yaml index f5a8f33..0d5c316 100644 --- a/.github/workflows/hive.yaml +++ b/.github/workflows/hive.yaml @@ -16,7 +16,7 @@ jobs: name: Run hive tests runs-on: ubuntu-latest # hive itself imposes no timeout; cap the job so a hang can't run forever. - timeout-minutes: 90 + timeout-minutes: 180 env: # `docker-local` -> `cross` bind-mounts this into the build container. LEAN_REPO_ROOT: ${{ github.workspace }} From d32715535a1c8e85eb094f003f4adfdf12c83337 Mon Sep 17 00:00:00 2001 From: SamAg19 Date: Mon, 27 Jul 2026 13:34:49 +0530 Subject: [PATCH 7/9] add hive test summary and gate CI behind run-hive label --- .github/workflows/hive.yaml | 15 ++++++++++----- lean_client/Makefile | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/.github/workflows/hive.yaml b/.github/workflows/hive.yaml index 0d5c316..1c9da11 100644 --- a/.github/workflows/hive.yaml +++ b/.github/workflows/hive.yaml @@ -1,11 +1,12 @@ name: Hive -# For now this runs on every pull request (plus manual dispatch) so we can -# confirm the pipeline works on CI. Once verified, gate it behind a `run-hive` -# label to avoid running the slow suite on every push. +# Runs on manual dispatch, and on pull requests only when they carry the +# `run-hive` label (added on label, and re-run on subsequent pushes) so the slow +# suite doesn't run on every PR push. on: - - pull_request - - workflow_dispatch + workflow_dispatch: + pull_request: + types: [labeled, synchronize] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -15,6 +16,10 @@ jobs: hive: name: Run hive tests runs-on: ubuntu-latest + # Skip on PRs unless the `run-hive` label is present; always run on dispatch. + if: >- + github.event_name != 'pull_request' || + contains(github.event.pull_request.labels.*.name, 'run-hive') # hive itself imposes no timeout; cap the job so a hang can't run forever. timeout-minutes: 180 env: diff --git a/lean_client/Makefile b/lean_client/Makefile index 37f90c9..fc76693 100644 --- a/lean_client/Makefile +++ b/lean_client/Makefile @@ -139,12 +139,43 @@ HIVE_REF := $(or $(HIVE_VERSION),master) .PHONY: test-hive test-hive: hive/hive docker-local - cd hive && ./hive --sim lean \ + @cd hive && \ + ./hive --sim lean \ --client-file simulators/lean/clients/devnet5.yaml \ --client grandine_lean_devnet5 \ --docker.output \ --docker.nocache="hive/clients/grandine_lean_devnet5" \ - --results-root ./workspace/logs + --results-root ./workspace/logs; \ + hive_status=$$?; \ + logs=./workspace/logs; \ + suites=$$(ls $$logs/*.json 2>/dev/null | grep -v '/hive\.json$$' || true); \ + if [ -z "$$suites" ]; then \ + echo "ERROR: hive produced no suite results - treating as an infrastructure/script failure."; \ + exit $$hive_status; \ + fi; \ + if ! command -v jq >/dev/null 2>&1; then \ + echo "jq not found; skipping summary. Raw results under $$logs"; \ + exit 0; \ + fi; \ + echo; \ + echo "==================== Hive test summary ===================="; \ + total=0; failed_total=0; \ + for f in $$suites; do \ + name=$$(jq -r '.name' "$$f"); \ + n=$$(jq '.testCases | length' "$$f"); \ + nf=$$(jq '[.testCases[] | select(.summaryResult.pass | not)] | length' "$$f"); \ + total=$$((total + n)); failed_total=$$((failed_total + nf)); \ + if [ "$$nf" -eq 0 ]; then \ + printf '%s: %d/%d passed\n' "$$name" "$$n" "$$n"; \ + else \ + printf '%s: %d/%d passed (%d failed)\n' "$$name" "$$((n - nf))" "$$n" "$$nf"; \ + jq -r '.testCases[] | select(.summaryResult.pass | not) | " FAIL: \(.name)"' "$$f"; \ + fi; \ + done; \ + echo "-----------------------------------------------------------"; \ + printf 'Total: %d/%d passed, %d failed\n' "$$((total - failed_total))" "$$total" "$$failed_total"; \ + echo "Full failure details: lean_client/hive/workspace/logs/details/"; \ + echo "===========================================================" hive/hive: hive/.hive-ref-$(HIVE_REF) @echo "==> Building hive binary (go build)..." From 4af541a9eb5a963b5e42f62b892e9460db7f80a5 Mon Sep 17 00:00:00 2001 From: SamAg19 Date: Mon, 27 Jul 2026 16:25:56 +0530 Subject: [PATCH 8/9] summarise hive results --- lean_client/Makefile | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/lean_client/Makefile b/lean_client/Makefile index fc76693..70bdc47 100644 --- a/lean_client/Makefile +++ b/lean_client/Makefile @@ -143,6 +143,7 @@ test-hive: hive/hive docker-local ./hive --sim lean \ --client-file simulators/lean/clients/devnet5.yaml \ --client grandine_lean_devnet5 \ + --sim.limit 'lean-spec-tests-verify-signatures' \ --docker.output \ --docker.nocache="hive/clients/grandine_lean_devnet5" \ --results-root ./workspace/logs; \ @@ -157,25 +158,31 @@ test-hive: hive/hive docker-local echo "jq not found; skipping summary. Raw results under $$logs"; \ exit 0; \ fi; \ + summary=$$( \ + echo "==================== Hive test summary ===================="; \ + total=0; failed_total=0; \ + for f in $$suites; do \ + name=$$(jq -r '.name' "$$f"); \ + n=$$(jq '.testCases | length' "$$f"); \ + nf=$$(jq '[.testCases[] | select(.summaryResult.pass | not)] | length' "$$f"); \ + total=$$((total + n)); failed_total=$$((failed_total + nf)); \ + if [ "$$nf" -eq 0 ]; then \ + printf '%s: %d/%d passed\n' "$$name" "$$n" "$$n"; \ + else \ + printf '%s: %d/%d passed (%d failed)\n' "$$name" "$$((n - nf))" "$$n" "$$nf"; \ + jq -r '.testCases[] | select(.summaryResult.pass | not) | " FAIL: \(.name)"' "$$f"; \ + fi; \ + done; \ + echo "-----------------------------------------------------------"; \ + printf 'Total: %d/%d passed, %d failed\n' "$$((total - failed_total))" "$$total" "$$failed_total"; \ + echo "Full failure details: lean_client/hive/workspace/logs/details/"; \ + echo "===========================================================" \ + ); \ echo; \ - echo "==================== Hive test summary ===================="; \ - total=0; failed_total=0; \ - for f in $$suites; do \ - name=$$(jq -r '.name' "$$f"); \ - n=$$(jq '.testCases | length' "$$f"); \ - nf=$$(jq '[.testCases[] | select(.summaryResult.pass | not)] | length' "$$f"); \ - total=$$((total + n)); failed_total=$$((failed_total + nf)); \ - if [ "$$nf" -eq 0 ]; then \ - printf '%s: %d/%d passed\n' "$$name" "$$n" "$$n"; \ - else \ - printf '%s: %d/%d passed (%d failed)\n' "$$name" "$$((n - nf))" "$$n" "$$nf"; \ - jq -r '.testCases[] | select(.summaryResult.pass | not) | " FAIL: \(.name)"' "$$f"; \ - fi; \ - done; \ - echo "-----------------------------------------------------------"; \ - printf 'Total: %d/%d passed, %d failed\n' "$$((total - failed_total))" "$$total" "$$failed_total"; \ - echo "Full failure details: lean_client/hive/workspace/logs/details/"; \ - echo "===========================================================" + printf '%s\n' "$$summary"; \ + if [ -n "$$GITHUB_STEP_SUMMARY" ]; then \ + { echo '```'; printf '%s\n' "$$summary"; echo '```'; } >> "$$GITHUB_STEP_SUMMARY"; \ + fi hive/hive: hive/.hive-ref-$(HIVE_REF) @echo "==> Building hive binary (go build)..." From 7c4ada1a3f727a11183b645a31fdfc524522e550 Mon Sep 17 00:00:00 2001 From: SamAg19 Date: Mon, 27 Jul 2026 17:00:01 +0530 Subject: [PATCH 9/9] Run all hive tests with summary enabled --- lean_client/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/lean_client/Makefile b/lean_client/Makefile index 70bdc47..3adbfd6 100644 --- a/lean_client/Makefile +++ b/lean_client/Makefile @@ -143,7 +143,6 @@ test-hive: hive/hive docker-local ./hive --sim lean \ --client-file simulators/lean/clients/devnet5.yaml \ --client grandine_lean_devnet5 \ - --sim.limit 'lean-spec-tests-verify-signatures' \ --docker.output \ --docker.nocache="hive/clients/grandine_lean_devnet5" \ --results-root ./workspace/logs; \