Repository navigation
feat(beacon): add Platåberget as a built-in network - #635
Conversation
🤖 Kimi Code ReviewI'll review this PR which adds Platåberget (Glamsterdam testnet) as a built-in network. This is primarily a configuration/network addition with minimal code changes. SummaryThe PR adds a new built-in network "plataberget" (Glamsterdam devnet-8) to the ethlambda client. The changes are mostly mechanical: adding config files, updating enum variants, and adjusting documentation. The code changes are in Detailed Review1.
|
| Severity | Location | Issue | Recommendation |
|---|---|---|---|
| Minor | bootstrap_nodes.yaml:20 |
Missing trailing newline | Add newline |
| Question | config.yaml:175,236 |
MAX_BLOBS_PER_BLOCK: 6 vs BLOB_SCHEDULE epoch 0: 21 |
Verify get_max_blobs_per_block correctly uses schedule |
Verdict
Approve with minor suggestion. The PR is well-structured, thoroughly tested, and correctly documented. The CONFIG_NAME override is handled cleanly. The only actionable item is adding a trailing newline to bootstrap_nodes.yaml.
Automated review by Kimi (Moonshot AI) · kimi-k2.6 · custom prompt
🤖 Claude Code ReviewReview of PR 635: add Platåberget as a built-in network Overall this looks good. I did not build or run the tests. Nothing I found blocks merging. Checked and fine
Nits, none blocking
Automated review by Claude (Anthropic) · sonnet · custom prompt |
🤖 Codex Code ReviewLooks good overall. I don’t see a consensus-critical regression in the Rust changes here; the PR is mostly adding a new built-in network and explicitly preserving existing “do not anchor built-ins at genesis” behavior.
No security, memory-safety, or performance issues jump out from the code touched in this PR. No fork-choice / attestation / justification-finalization / SSZ correctness concerns are introduced by these changes. Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
Platåberget is the long-lived Glamsterdam testnet (glamsterdam-devnet-8), meant to run for months as the place to test post-Glamsterdam Ethereum before Sepolia and Hoodi fork. It is the one public chain already past gloas, so building it in gives the gloas follower a live target: once the follower takes gloas blocks, `--network plataberget` follows it without fetching a network directory. It has no eth-clients repo, so its config.yaml and bootstrap_nodes.yaml come byte for byte from ethpandaops/glamsterdam-devnets' network-configs/devnet-8. The genesis values are read off that directory's genesis.ssz and match what its checkpoint provider serves. The root and both fork versions are pinned offline by the digests its bootnode ENRs publish, from both sides of the gloas fork. The file says `CONFIG_NAME: 'testnet'`, a placeholder ethpandaops keeps for Prysm, so a built-in network now takes its CONFIG_NAME from its `--network` name. The eth-clients files already carry their own names, so nothing changes for mainnet, Sepolia or Hoodi. Checkpoint sync against Platåberget downloads a gloas anchor and verifies it against these genesis values, then stops at `refuse_unfollowable_fork`, since the follower does not take gloas blocks yet.
61f249c to
d91c6e5
Compare
ethpandaops re-signed every devnet-8 bootnode ENR on 2026-10-09 (glamsterdam-devnets f271042f, "bump erigon"). Two of the twenty hosts (168.144.43.157, 64.23.215.76) also rotated their node keys, so the embedded entries named peer ids those hosts no longer answer to, both for the static dial and as discv5 seeds. The other eighteen keep their key, address and ports and only carry a higher seq. Every refreshed ENR now carries the gloas digest, so the comment on the fulu digest pin no longer holds for the embedded file. The pin stays; the comment now points at the upstream revision that published it.
Auto-merge was disabled for another pull request in the stack
Main gained the gloas stack (#634, #635, #639, #662, #663). Adapted to it: - require_validated and the syncing endpoint's head check read optimism through block_is_optimistic, which knows a gloas block's payload link. - payload_attestation_data follows attestation data's rule: a 503 without an execution client, or when the voted block's payload is unvalidated. - The gloas validator-client tests serve through an idle execution client, and the optimistic-head test names the fork attestation_data now takes.
Main gained the gloas stack (#634, #635, #639, #662, #663). Adapted to it: - Gloas block production (produceBlockV4) appends the client versions to the graffiti the way fulu's does. - The validator client's gloas proposal and duties tests take their graffiti and fee recipient from ProposerSettings, and a validator's own graffiti is checked to reach a gloas block request.
Main gained the gloas stack (#634, #635, #639, #662, #663). Adapted to it: - The BLS fixture tests follow main's cryptography-specs layout, and main's Makefile (gossip vectors in the pinned tree) replaces the separate gossip tree this branch extended. - Operations under a gloas head are IGNOREd and a gloas-shaped attester slashing has no consumer; gloas operation vectors are not run. - Published columns and operations go out under the slot's own digest, and column subnets use compute_subnet_for_data_column_sidecar. - Gloas block production packs from the store's attestation pool, and a published gloas block gossips no sidecars (its columns follow the envelope). The payload attestation pool stays a shared handle.
Main gained the gloas stack (#634, #635, #639, #662, #663). Adapted to it: the write cursor also drives gloas's progressive registry. A cursor pass crosses a ProgressiveList's subtrees with global indices, and try_update_validators_with_balances and try_update_balances work on any BeaconState, so electra's effective-balance step and the reward deltas write through them too.
Main gained the gloas stack (#634, #635, #639, #662, #663). Adapted to it: gloas block processing (its attestations and sync aggregate) reads the total active balance from the same cache, which gloas block production passes in, and the cache's registry scan walks iter_validators so it covers gloas's progressive registry.
Main gained the gloas stack (#634, #635, #639, #662, #663). Adapted to it: gloas's progressive inactivity scores and ring buffers go through the same element accessors (inactivity_score_mut, InactivityScoresRef), and ProgressiveList is Buffered. Main's new tests write block_roots by index rather than through iter_mut, which a tree-backed vector has not got.
Main gained the gloas stack (#634, #635, #639, #662, #663). Adapted to it: - The key-layout bump is DB_VERSION 7, since main spends 6 on #634's gloas config keys. - A gloas fork-choice test stores a state whose header slot is its block's, since states are keyed by that slot, and the slot-peek test covers a gloas block, now the newest fork.
Main gained the gloas stack (#634, #635, #639, #662, #663). Adapted to it: gloas aggregates are checked under the schedule's attester domain too (is_valid_indexed_attestation_with_domain), main's attestation_for test helper signs under the schedule's domain, and the test store helpers are main's beacon_store_with_config.
🗒️ Description / Motivation
Platåberget is the long-lived Glamsterdam testnet (glamsterdam-devnet-8). It is the one public chain already past gloas: it started at fulu and forked to gloas at epoch 1536 (around 2026-08-20). That makes it the live target for the gloas follower this PR stacks on (#634).
This PR adds
--network platabergetas a built-in network, next to mainnet, Sepolia and Hoodi.What Changed
Embedded chain (
bin/ethlambda/src/network/built_in.rs,bin/ethlambda/assets/plataberget/)BuiltInNetwork::Plataberget, withconfig.yamlandbootstrap_nodes.yamlcopied byte for byte fromethpandaops/glamsterdam-devnets'network-configs/devnet-8/metadata(bootnodes as of upstreamf271042f, 2026-10-09). There is noeth-clientsrepo for it.genesis_time1786622400 (2026-08-13 12:00 UTC),genesis_validators_root0xbb4a1a9e…. Both come from the publishedgenesis.ssz, matchgenesis_validators_root.txt, and match whatcheckpoint-sync.plataberget.ethpandaops.io/eth/v1/beacon/genesisreturns.CONFIG_NAMEcomes from--network(BuiltInNetwork::resolve)CONFIG_NAME: 'testnet', a placeholder ethpandaops keeps for Prysm. Without an override,--network platabergetwould log and reporttestnet.resolvenow sets every built-in'sCONFIG_NAMEto its--networkname. Theeth-clientsfiles already carry their own names, so nothing changes for mainnet, Sepolia or Hoodi.Offline pins (tests in
built_in.rs)GLOAS_FORK_EPOCHand deposit chain id are read from the file, not defaulted to mainnet's.5c943807: fulu at genesis, from the ENRs signed before the fork. Upstream re-signed every bootnode on 2026-10-09, so this one is in the file's earlier revision (30e82900), not the embedded one.98c910cf: gloas, from the ENRs signed after it (every ENR in the embedded file).Docs: every list of built-in networks (
README.md,docs/cli.md,docs/beacon_wire.md,docs/checkpoint_sync.md,CLAUDE.md, the--networkhelp). "Every built-in network has been live for years" became "is a live chain", since this one launched in August.Limitations
The follower can't follow Platåberget yet. Checkpoint sync succeeds: the anchor decodes as gloas and passes the genesis checks against the new constants. Then
refuse_unfollowable_forkrefuses it, since the chain actor does not take gloas blocks yet. That changes once the follower takes gloas blocks and anchors.How to Test
cargo test -p ethlambda --profile release-fast --bins network:: ethlambda beacon --network plataberget --checkpoint-sync-url https://checkpoint-sync.plataberget.ethpandaops.ioThe second command resolves the network (the digest at the current epoch is gloas's
98c910cf). It downloads and verifies the finalized anchor, then refuses it: