From 0b2d85df344897229e214dc05e054aa34dbcc1ea Mon Sep 17 00:00:00 2001 From: iurii Date: Sat, 27 Jun 2026 22:54:07 +0300 Subject: [PATCH 1/3] add params-gloas.yaml for ePBS (EIP-7732 / Gloas) fork-transition testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors params-boole.yaml: genesis on Fulu, forking into Gloas at epoch 2, using ethpandaops glamsterdam-devnet-5 client images (stock geth/lighthouse don't implement EIP-7732) and a Gloas-aware genesis generator (6.0.8; the ethereum-package@6.1.0 default 5.3.5 predates Gloas). SSV-side Boole active from genesis (boole_epoch: 0). Monitor/E2M disabled — it can't parse Gloas blocks (decodes via go-eth2-client, which has no Gloas types). Wires a `make run-gloas` convenience target + README/help entries. --- Makefile | 6 ++++ README.md | 2 ++ params-gloas.yaml | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 params-gloas.yaml diff --git a/Makefile b/Makefile index 7fcd0dc..2657132 100644 --- a/Makefile +++ b/Makefile @@ -185,6 +185,7 @@ help: @echo "Network scenarios:" @echo " make run Default: Fulu (all forks active)" @echo " make run-boole Boole fork at epoch 3, Fulu at epoch 5" + @echo " make run-gloas Gloas/ePBS fork at epoch 2 (devnet-5 images)" @echo " make run PARAMS_FILE=custom.yaml Custom params" @echo "" @echo "Configuration:" @@ -203,6 +204,11 @@ run-boole: ensure-keys @echo "──── Starting SSV testnet (Boole fork at epoch 3) ────" kurtosis run --enclave $(ENCLAVE_NAME) --args-file params-boole.yaml . +.PHONY: run-gloas +run-gloas: ensure-keys + @echo "──── Starting SSV testnet (Gloas/ePBS fork at epoch 2) ────" + kurtosis run --enclave $(ENCLAVE_NAME) --args-file params-gloas.yaml . + # ── Tests ──────────────────────────────────────────────────────────── .PHONY: test-faulty-el diff --git a/README.md b/README.md index 182947b..4e5fc82 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ make help |---------|-------------| | `make run` | Start testnet (default: Fulu, all forks active) | | `make run-boole` | Start with Boole fork at epoch 3, Fulu at epoch 5 | +| `make run-gloas` | Start with Gloas/ePBS (EIP-7732) fork at epoch 2 (devnet-5 images) | | `make reset` | Clean + restart from genesis | | `make show` | Show running services and ports | | `make logs` | Tail ssv-node-0 logs (`SERVICE=ssv-node-1` for others) | @@ -99,6 +100,7 @@ use_static_keys: true # false = regenerate keys at runtime (~40s slower) Pre-built configs: - `params.yaml` — Fulu at genesis (default) - `params-boole.yaml` — Electra→Boole→Fulu fork transitions +- `params-gloas.yaml` — Fulu→Gloas (ePBS/EIP-7732) transition; needs `SSV_COMMIT=epbs-gloas make prepare` and ethpandaops glamsterdam-devnet-5 client images (monitor/E2M disabled — can't parse Gloas) ```bash make run PARAMS_FILE=params-boole.yaml diff --git a/params-gloas.yaml b/params-gloas.yaml new file mode 100644 index 0000000..bf01d09 --- /dev/null +++ b/params-gloas.yaml @@ -0,0 +1,70 @@ +# Gloas / ePBS (EIP-7732) fork-transition test: genesis on Fulu, forks into Gloas at epoch 2. +# Usage: SSV_COMMIT=epbs-gloas make prepare && make run-gloas +# (or: make run PARAMS_FILE=params-gloas.yaml) +# +# Clients: ethpandaops glamsterdam-devnet-5 builds — the stock geth/lighthouse releases used by +# params.yaml do NOT implement EIP-7732. The genesis generator is pinned to a Gloas-aware build +# (the ethereum-package@6.1.0 default, 5.3.5, predates Gloas). +# +# Gloas is purely beacon-driven on the SSV side: the node reads GLOAS_FORK_EPOCH from the beacon +# node's /config/spec at runtime, so no SSV-side fork knob is needed. Boole (the SSV protocol fork +# ePBS builds on) must be active, though — hence boole_epoch: 0 (default is disabled). +# +# Monitor (E2M) is disabled: the ethereum2-monitor image cannot parse Fulu/Gloas beacon blocks +# (it decodes via go-eth2-client, which has no Gloas types). Observe ePBS via the SSV node logs +# and dora. Re-enable once E2M gains Gloas support. + +network: + participants: + - el_type: geth + el_image: ethpandaops/geth:glamsterdam-devnet-5 + cl_type: lighthouse + cl_image: ethpandaops/lighthouse:glamsterdam-devnet-5 + validator_count: 32 + count: 2 + supernode: true + + additional_services: + - dora + + # dora's default image can't render Gloas blocks; pin the devnet-5 build. + dora_params: + image: ethpandaops/dora:master-0e63023 + + # 6.1.0's default generator (5.3.5) predates Gloas; pin the devnet-5 build. + ethereum_genesis_generator_params: + image: ethpandaops/ethereum-genesis-generator:6.0.8 + + network_params: + network_id: "3151908" + deneb_fork_epoch: 0 + electra_fork_epoch: 0 + fulu_fork_epoch: 0 # Fulu must precede Gloas — activate at genesis + gloas_fork_epoch: 2 # ePBS fork; small so the transition lands a few minutes in (tune freely) + perfect_peerdas_enabled: false + preregistered_validator_count: 74 + + port_publisher: + cl: + enabled: true + +use_static_keys: true + +monitor: + enabled: false + +boole_epoch: 0 # SSV Boole fork active from genesis (ePBS builds on Boole); default is disabled + +nodes: + ssv: + count: 4 + anchor: + count: 0 + +images: + ssv: "node/ssv" + anchor: "sigp/anchor:v1.2.0" + monitor: "monitor" + redis: "redis:7.4.2" + postgres: "postgres:15" + deployer: "localssv/ssv-network" From f53dce56f2b13373dd5d258e4b14e6660564335e Mon Sep 17 00:00:00 2001 From: iurii Date: Sun, 28 Jun 2026 10:53:07 +0300 Subject: [PATCH 2/3] check-deps: guard against low Docker disk (geth low-disk shutdown) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Geth self-terminates below its ~1.62GiB low-disk safety threshold, silently freezing the chain mid-run (EL exits → CL gets no payloads → stuck at slot ~1). This surfaced as a confusing deploy "hang" / executor timeout. Add a fail-fast disk check to check-deps (default >=10GiB, MIN_DISK_GIB override) and wire check-deps into run-gloas/run-boole so every run path gets it. --- Makefile | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 2657132..4d6d4ad 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,10 @@ ENCLAVE_NAME?=localnet PARAMS_FILE?=params.yaml SSV_NODE_COUNT?=4 SSV_COMMIT?=stage +# Minimum free disk (GiB) in the Docker VM before a run. Geth self-terminates below its +# ~1.62GiB low-disk safety threshold, which freezes the chain mid-run (EL gone → CL gets no +# payloads). Guarded with headroom by check-deps; override for tiny/large runs. +MIN_DISK_GIB?=10 default: run @@ -15,6 +19,13 @@ check-deps: @command -v docker >/dev/null 2>&1 || { echo "Error: docker not found. Install: https://docs.docker.com/get-docker/"; exit 1; } @command -v kurtosis >/dev/null 2>&1 || { echo "Error: kurtosis not found. Install: https://docs.kurtosis.com/install"; exit 1; } @docker info >/dev/null 2>&1 || { echo "Error: Docker daemon not running. Start Docker/OrbStack first."; exit 1; } + @avail=$$(docker run --rm alpine df -P / 2>/dev/null | awk 'NR==2{printf "%d", $$4/1024/1024}'); \ + if [ -n "$$avail" ] && [ "$$avail" -lt "$(MIN_DISK_GIB)" ]; then \ + echo "Error: Docker VM has only $${avail}GiB free (need >= $(MIN_DISK_GIB)GiB)."; \ + echo " Geth self-terminates below ~1.62GiB free (low-disk safety), freezing the chain mid-run."; \ + echo " Free space: docker builder prune -af && docker system prune -f (or raise Docker Desktop's disk image size)."; \ + exit 1; \ + fi .PHONY: run run: check-deps ensure-keys @@ -200,12 +211,12 @@ help: # ── Network scenarios ──────────────────────────────────────────────── .PHONY: run-boole -run-boole: ensure-keys +run-boole: check-deps ensure-keys @echo "──── Starting SSV testnet (Boole fork at epoch 3) ────" kurtosis run --enclave $(ENCLAVE_NAME) --args-file params-boole.yaml . .PHONY: run-gloas -run-gloas: ensure-keys +run-gloas: check-deps ensure-keys @echo "──── Starting SSV testnet (Gloas/ePBS fork at epoch 2) ────" kurtosis run --enclave $(ENCLAVE_NAME) --args-file params-gloas.yaml . From 07c0bd34a7db9196e6c424f8e134707313c52ac6 Mon Sep 17 00:00:00 2001 From: iurii Date: Mon, 29 Jun 2026 20:34:05 +0300 Subject: [PATCH 3/3] docs(local_testnet): clarify disk-check semantics + flag moving devnet tags Non-blocking review feedback on PR #34: - check-deps: note the df measures the Docker storage backend (a proxy for geth's volume, not an exact reading) and that the guard fails open when `docker run` can't execute; soften the error wording to match. - params-gloas.yaml: flag glamsterdam-devnet-5 / dora master-* as moving tags left unpinned on purpose to track devnet-5. --- Makefile | 6 +++++- params-gloas.yaml | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4d6d4ad..42682a5 100644 --- a/Makefile +++ b/Makefile @@ -19,9 +19,13 @@ check-deps: @command -v docker >/dev/null 2>&1 || { echo "Error: docker not found. Install: https://docs.docker.com/get-docker/"; exit 1; } @command -v kurtosis >/dev/null 2>&1 || { echo "Error: kurtosis not found. Install: https://docs.kurtosis.com/install"; exit 1; } @docker info >/dev/null 2>&1 || { echo "Error: Docker daemon not running. Start Docker/OrbStack first."; exit 1; } +# Approximate free space in the Docker storage backend: the alpine overlay and Kurtosis volumes +# (where geth's chaindata lives) share the VM data-root on Docker Desktop/OrbStack, so this is a +# good proxy rather than an exact volume measurement. Fails open — if `docker run` can't execute +# (offline, registry/proxy blocked) avail is empty and the check is skipped, not failed. @avail=$$(docker run --rm alpine df -P / 2>/dev/null | awk 'NR==2{printf "%d", $$4/1024/1024}'); \ if [ -n "$$avail" ] && [ "$$avail" -lt "$(MIN_DISK_GIB)" ]; then \ - echo "Error: Docker VM has only $${avail}GiB free (need >= $(MIN_DISK_GIB)GiB)."; \ + echo "Error: Docker storage backend has only ~$${avail}GiB free (need >= $(MIN_DISK_GIB)GiB)."; \ echo " Geth self-terminates below ~1.62GiB free (low-disk safety), freezing the chain mid-run."; \ echo " Free space: docker builder prune -af && docker system prune -f (or raise Docker Desktop's disk image size)."; \ exit 1; \ diff --git a/params-gloas.yaml b/params-gloas.yaml index bf01d09..83884aa 100644 --- a/params-gloas.yaml +++ b/params-gloas.yaml @@ -6,6 +6,11 @@ # params.yaml do NOT implement EIP-7732. The genesis generator is pinned to a Gloas-aware build # (the ethereum-package@6.1.0 default, 5.3.5, predates Gloas). # +# Heads-up — the devnet image tags below (glamsterdam-devnet-5 for geth/lighthouse, dora master-*) +# are MOVING targets that ethpandaops re-pushes as the devnet advances; they're left unpinned on +# purpose to track devnet-5. If a future run breaks genesis or the transition, a re-pushed image is +# a prime suspect — refresh the tags, or pin a @sha256: digest once devnet-5 stabilizes. +# # Gloas is purely beacon-driven on the SSV side: the node reads GLOAS_FORK_EPOCH from the beacon # node's /config/spec at runtime, so no SSV-side fork knob is needed. Boole (the SSV protocol fork # ePBS builds on) must be active, though — hence boole_epoch: 0 (default is disabled).