Skip to content

Gloas (ePBS) testnet profiles for Anchor epbs testing - #33

Draft
shane-moore wants to merge 7 commits into
ssvlabs:mainfrom
shane-moore:gloas-epbs-testing
Draft

Gloas (ePBS) testnet profiles for Anchor epbs testing#33
shane-moore wants to merge 7 commits into
ssvlabs:mainfrom
shane-moore:gloas-epbs-testing

Conversation

@shane-moore

@shane-moore shane-moore commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

What this adds

Two Gloas (EIP-7732 / ePBS) testnet profiles for ssv-mini, so Anchor's epbs branch can be
exercised end to end on a local Glamsterdam-style chain with its own genesis and SSV contracts:
block proposal through the ePBS block structure, and attestation against the new 3s Gloas deadline.
A 4-operator all-Anchor cluster does real duties; no go-SSV nodes involved.

Built for Anchor devs: point it at your epbs work and watch the cluster propose and attest on a
Gloas chain.

Quick start

ANCHOR_COMMIT=epbs make prepare-anchor   # build node/anchor from sigp/anchor epbs
make run-gloas                           # Gloas at genesis, 4-operator all-Anchor cluster
make logs SERVICE=anchor-node-0          # tail an operator

ePBS is gated on the Ethereum Gloas fork (gloas_fork_epoch); there is no SSV-side fork knob. The
epbs branch already carries this model, so a plain ANCHOR_COMMIT=epbs build is all you need.

Requires Docker and a recent Kurtosis CLI (1.19.x; 1.15.x rejects a GpuConfig builtin in the
pinned ethereum-package). Full walkthrough and edge cases are in the new "Gloas (ePBS) testnet"
section of the README.

Testing your own Anchor changes

prepare-anchor builds node/anchor from any branch/tag/commit on your ../anchor clone's origin:

ANCHOR_COMMIT=my-epbs-feature make prepare-anchor && make run-gloas

Or build the image straight from your working tree and skip prepare entirely:

cd ../anchor && docker build -f Dockerfile.devnet -t node/anchor .
cd ../ssv-mini && make reset PARAMS_FILE=params-gloas.yaml   # scoped teardown + re-run

Either way the profile consumes whatever is tagged node/anchor. There is no hot-swap for Anchor
nodes (unlike restart-ssv-nodes), so the iteration loop is: rebuild the image, then make reset.

The two profiles

Profile Command Exercises
params-gloas.yaml make run-gloas Gloas at genesis, 4 Anchor operators, 10 keyshare validators registered on-chain. Proposal duty (attestation timing needs the #1061 fix in the image).
params-gloas-builders.yaml make run-gloas-builders Above plus 2 genesis ePBS builders and buildoor: external bids, payload reveals, chain-level PTC (payload_attestations).

Reference behavior (tell a regression from a known gap)

Measured live on an epbs image without #1061, local devnet:

  • Proposals work. Cluster publishes Gloas blocks ~+0.13s into the slot, canonical (verified on-chain: multiple cluster-proposed slots, all canonical=true, "Successfully published block" on every operator).
  • Attestations: broken without #1061; working only once #1061 is also applied. Measured on an epbs image without #1061: 0 cluster attestations published, even though the attestation QBFT reaches COMMIT consensus. The sync-committee half stalls and takes submission down with it (see the #1061 note below). With #1061 also in the image, attestations publish ~+4.09s vs the 3.0s Gloas deadline (QBFT itself ~15ms; the remaining gate is the committee partial-signature batch waiting on the sync-message flow, which fires on Lighthouse's static 4s sync timer; head-event pipeline healthy at ~+0.12s). That ~+4.09s is an Anchor/LH timing-wiring gap, not a cluster failure, and is identical on every operator.
  • Cluster-proposed slots are execution-empty by design. Anchor self-builds and never reveals the payload (SIP-94 envelope stub), so PTC votes payload_present=false on them and the EL does not advance that slot. Expected, not a bug.
  • Gloas is gated on the Ethereum fork; SSV attestations need the #1061 fix in your anchor image. ePBS activates purely from gloas_fork_epoch; there is no SSV-side fork knob. With Gloas active the committee runs GloasBeaconVote for attestations, but the sync-committee signing path still runs BeaconVote (feat(validator_store): migrate sign_committee_sync_committee_signatures to GloasBeaconVote at CStar sigp/anchor#1061, open), so the two resolve to different QBFT instances instead of sharing one. Observed mechanism: the attestation instance reaches COMMIT, but the sync instance round-changes every slot and never completes, and because the committee's post-consensus partial-signature batch is sized to attestations + sync messages, it never fills, so the agreed attestation is never submitted (0 published, every operator). So attestation testing needs an anchor image carrying #1061; proposals, external-builder bids, and chain-level PTC work regardless. (Consensus succeeds; only submission is blocked.)

Related Anchor issues: sigp/anchor#1061 (sync GloasBeaconVote migration; required for SSV attestations), sigp/anchor#1082 / #1078 (PTC duties).

Mechanics worth knowing

  • Imports a forked ethereum-package pin (shane-moore/ethereum-package, by commit), fetched automatically by Kurtosis. Needed because Gloas genesis requires ethereum-genesis-generator >= 6.0.0 (no tagged release ships it) plus a one-line fix so genesis ePBS builders do not collide with the preregistered keyshare validators (indices 64-73).
  • Uses nethermind + lighthouse glamsterdam-devnet-5 images (geth has no Glamsterdam build).
  • Registration scripts carry two live-verified fixes: explicit gas limits (nethermind's eth_estimateGas underestimates SSVNetwork delegatecall paths ~3x) and msg.value on the payable v2.0.0 bulkRegisterValidator.
  • register_validators (default false) gates on-chain registration so the default aetheria flow is untouched; the Gloas profiles set it true so operators get duties.
  • All-Anchor cluster (ssv.count: 0): no node/ssv image needed, and monitor is disabled.

Why draft

This is a testing tool for the in-flight epbs work, not a finished feature. Opening as draft for
visibility and so Anchor devs can use it now; happy to adjust scope or take out of draft per review.

shane-moore and others added 7 commits June 12, 2026 16:51
- Point ethereum-package imports at a fork pin (main @ d47e987 + one
  fix): Gloas genesis needs ethereum-genesis-generator >= 6.0.0, which
  no tagged release carries, and upstream's builder_count collides with
  preregistered_validator_count (builders derive from the same mnemonic
  starting at the participant validator sum, landing on the keyshare
  validators 64-73). Branch:
  shane-moore/ethereum-package@ssv-mini/builder-skip-preregistered.
- params-gloas.yaml: nethermind+lighthouse glamsterdam-devnet-5 images,
  Gloas at genesis, 4-operator all-Anchor cluster, validators 64-73
  registered on-chain. cstar_epoch deliberately omitted: scheduling
  CStar before sigp/anchor#1061 lands breaks attestations cluster-wide
  (sync path equivocates against the attestation path on the shared
  wire MessageId, gossipsub graylists the operators within ~4 epochs).
- Flag-gated validator registration (register_validators, default
  false): restores Step 4 for standalone runs without touching the
  aetheria local_testnet flow. Registration fixes verified live:
  explicit gas limits (nethermind eth_estimateGas underestimates
  SSVNetwork delegatecall paths ~3x, inner OOG via the 63/64 rule) and
  msg.value on the payable v2.0.0 bulkRegisterValidator (reverts
  InsufficientBalance without it).
- Conditional cstar entry in the Anchor fork-schedule template
  (cstar_epoch arg), for when #1061 lands.
- Anchor nodes expose Prometheus metrics on port 5164 (duty timing,
  head-event trigger counters).
- Makefile: ANCHOR_COMMIT parameter for prepare-anchor, run-gloas and
  run-gloas-builders targets.

Regression: default params.yaml verified on the new pin (geth+lighthouse,
contracts, static keys, 4 SSV nodes; monitor skipped, image currently
unbuildable since ssvlabs/ethereum2-monitor is not accessible).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
params-gloas-builders.yaml adds builder_count: 2 (genesis ePBS builders
with 0x03 credentials, kept in the separate Gloas BeaconState.builders
registry) and mev_type buildoor. Exercises the payload half of ePBS:
external builder bids via gossip, payload reveals, and chain-level PTC
(payload_attestations from the lighthouse VC validators).

Measured on this profile: ~40% of LH-proposed slots take the external
bid; Anchor cluster proposers self-build 22/22 (no builder registration
or proposer preferences yet) and their payloads are never revealed
(SIP-94 envelope stub), so cluster slots are execution-empty. The
gating Anchor work for complete ePBS proposals is the bid-targeting
path, not envelope signing.

Requires the forked ethereum-package pin from the previous commit
(upstream builder placement collides with the preregistered keyshare
validator range).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dedicated section covering both Gloas profiles end to end: the
prepare-anchor + run-gloas flow, what each profile exercises, and the
non-obvious edge cases a teammate hits (Kurtosis >=1.19 for the
GpuConfig builtin, the forked ethereum-package pin and why it exists,
the deliberate no-CStar omission per sigp/anchor#1061, prepare-anchor
moving ../anchor's HEAD, all-Anchor cluster needing no node/ssv or
monitor, builders living in BeaconState.builders, and cluster slots
being execution-empty by SIP-94 design).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…or #1090)

sigp/anchor#1090 removes the SSV Fork::CStar variant and gates ePBS/Gloas
behavior on the Ethereum fork (spec...gloas_enabled()) instead of an
SSV-side fork ordinal, so there is no longer a cstar_epoch knob.

- Remove the conditional cstar entry from the ssv_fork_schedule.yaml
  template and the HasCStar/CStarEpoch render data (utils.star). The
  emitted schedule is now Alan + Boole only, valid on pre- and post-#1090
  anchor images alike (we never emitted a cstar entry regardless).
- Rewrite the profile/README/CLAUDE narrative: Gloas activates purely from
  gloas_fork_epoch. The previous "omit cstar_epoch to dodge #1061" guidance
  no longer applies, because #1090 moves the attestation signing gate to
  gloas_enabled(), so gloas-at-genesis now drives GloasBeaconVote committee
  consensus from slot 0. With the sync signing path still unmigrated
  (sigp/anchor#1061, open), SSV cluster attestations now require an anchor
  image carrying the #1061 fix; proposals, external-builder bids, and
  chain-level PTC remain testable regardless.

Supersedes the approach in sigp/anchor#1085 (fork reorder).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n-break mechanism

Validated live on a #1090 (rip-cstar) image: proposals canonical (+0.13s), but
attestations are never submitted. The attestation QBFT reaches COMMIT; the
sync-committee BeaconVote instance round-changes forever, and the committee
post-consensus partial-signature batch (sized to attestations + sync) never
fills. Replaces the imprecise 'equivocation/graylist' framing. Adds a rip-cstar
build note until #1090 merges into epbs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…g note

CStar is removed by #1090, so drop the removal backstory from the build note and
params headers (keep only the rip-cstar branch name and the one #1061 explanation).
Mark attestation timing as needing the #1061 fix in the image.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
anchor #1090 (remove SSV Fork::CStar, gate ePBS on the Ethereum Gloas fork)
has merged into epbs. Drop the "build from rip-cstar until #1090 lands"
instruction and the #1090-removed-CStar backstory; state the model directly
(ePBS gated on gloas_fork_epoch, no SSV-side fork knob) and reword the
measurement notes to "epbs image without #1061". Keep the #1061 attestation
caveat intact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant