Repository navigation
feat(beacon): schedule Hoodi Glamsterdam, resume across a fork scheduled ahead of the directory - #677
Conversation
🤖 Claude Code ReviewReview: PR 677, schedule Glamsterdam in the built-in Hoodi configI reviewed this from the diff alone and didn't build or run the tests. The change only touches Points to check
The change is low risk and I found no bugs. I'd confirm point 2 with the tests before merging and add the CLAUDE.md note from point 1. Automated review by Claude (Anthropic) · sonnet · custom prompt |
🤖 Kimi Code ReviewI'll review this PR diff focusing on the configuration additions for the "Gloas" fork. Let me analyze each aspect carefully. Overall AssessmentThis PR adds configuration parameters for a new fork named "Gloas" to the Hoodi testnet configuration. I have several concerns ranging from naming inconsistencies to potential consensus-critical issues. Critical Issues1. Typo in Fork Name: "Gloas" vs "Gloss" / "Gasper"File: The fork name "Gloas" appears to be a typo. Ethereum consensus forks follow thematic naming:
"Gloas" is not a recognized word; "Gloss" (a type of star/surface brightness) or this may be intended as something else. If this is a typo, it will cause fork version mismatches with other clients. Verify: Is this the canonical name from the specification? If not, this is a consensus-critical bug. 2. Duplicate/Conflicting Parameter NamesFile:
Lines 93, 95: These parameters lack the 3. Missing
|
| Severity | Count | Key Items |
|---|---|---|
| Critical | 2 | Name typo (Item 1), ambiguous global params (Item 2) |
| High | 2 | Churn quotient change, activation/exit split (Items 4-5) |
| Medium | 2 | Gas limit magnitude, request payload context (Items 6-7) |
Recommendation: Do not merge until the "Gloas" naming is verified against canonical specification and the parameter suffix inconsistencies in Items 2 and 5 are resolved with explicit documentation.
Automated review by Kimi (Moonshot AI) · kimi-k2.6 · custom prompt
🤖 Codex Code ReviewLooks good overall. This PR only updates Review
One thing to verify
No other issues stood out from this diff. Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
eth-clients/hoodi scheduled Gloas at epoch 132352 (2026-10-26 17:42:48 UTC) in eth-clients/hoodi#31. The built-in Hoodi config is that repo's file byte for byte, so this copies it again at ef89989. A build that claims the GLOAS_* keys needs this to follow Hoodi across the fork: without it, the node keeps the fulu fork digest past epoch 132352 and falls off the chain there. A build that does not claim them only reports the new keys as ignored, the same as it already does for Sepolia.
Scheduling a fork edits exactly the fields a beacon resume compared for equality, so every existing directory was refused with ConfigChanged the first time its node started with the new schedule. Hoodi's Glamsterdam schedule is the first case: on a build that claims GLOAS_*, every Hoodi directory stores gloas as unset and would need a fresh checkpoint sync. A fork's version and epoch now only have to agree once the directory has processed that fork under either schedule: both epochs must lie past the latest epoch it holds a block or state of (the highest LiveChain slot, or the finalized state's slot when later). BLOB_SCHEDULE entries follow the same rule. A fork moved onto or off a processed epoch is still refused, since those blocks were validated under the other schedule. Accepting the change is not enough on its own, because the node runs on the persisted config. A resume that passes now writes the config file over Metadata["config"] (Store::replace_config), so the file's values, CONFIG_NAME included, are the ones the node runs on and reports.
fc9d481 to
de572e7
Compare
…#634) Squash of feat/beacon-gloas at 1d667c4 (merge-base 35c074b). Adapted onto #626-#633 and main (#642-#677): - #632/#633's epoch single pass ported to the element accessors; fulu runs through the single pass, with the eth1-bridge gate on electra only. - DB_VERSION 6 (gloas Config 5 + #628's table). - compute_node_weights skips the boost outside the justified subtree (boost_reaches_the_descent), for #627's LiveChain prune; the boosted-finalized-block bound test is dropped and the differential tests skip pruned roots. - #628's set_unrealized_justification slot argument in the tests; get_forkchoice_store keeps the anchor block's slot. - #653's validator-by-id handler on iter_validators/balance.
Squash of feat/beacon-gloas-live at d1ef2fe (merge-base d91c6e5). Adapted onto #626-#638 and main (#642-#677): - 13 tables (#628's BeaconUnrealizedJustifications beside the gloas two). - #626's event bus, test stand-ins and BlockAnnouncement carry the gloas sidecar and the two gloas chain-actor messages. - The Beacon API's optimism readers (syncing, fork, validator-by-id, sync duties, require_validated) go through block_is_optimistic. - #643's liveness recorder ignores envelopes and payload attestations.
## 🗒️ Description / Motivation Hoodi's Glamsterdam fork is unscheduled: [eth-clients/hoodi#33](eth-clients/hoodi#33) calls off the Gloas activation planned for epoch **132352** (2026-10-26 17:42:48 UTC), which #677 picked up. Our built-in Hoodi config is eth-clients' file byte for byte, so it follows. ## What Changed `bin/ethlambda/assets/hoodi/config.yaml` is copied again from `eth-clients/hoodi` at `987ca9a` (#33's head): | Key | Before | After | |---|---|---| | `GLOAS_FORK_EPOCH` | `132352` | `18446744073709551615` (far future) | | `GAS_LIMIT_SCHEDULE` | 200M gas at `132352` | removed | `GLOAS_FORK_VERSION` and the Gloas preset/timing keys stay, since upstream keeps them so the fork can be rescheduled with one epoch change. `bootstrap_nodes.yaml` already matches upstream. ## Correctness / Behavior Guarantees | Build | Effect | |---|---| | `main` | Gloas keys are ignored here, so only `GAS_LIMIT_SCHEDULE` drops out of the ignored-keys warning | | A gloas build | No longer activates Gloas on 2026-10-26, so it stays on the same chain as the rest of Hoodi. Existing directories resume: both the old and the new epoch are ahead of anything processed, which `first_config_difference` accepts since #677 | > [!NOTE] > eth-clients/hoodi#33 is still open at the time of writing. If its final version differs, this file should be re-copied before merging. ## Tests Added / Run No new tests: nothing pins Hoodi's Gloas epoch. ```bash cargo test -p ethlambda --bins --profile release-fast git clone https://github.com/eth-clients/hoodi && git -C hoodi fetch origin pull/33/head && git -C hoodi checkout FETCH_HEAD cmp bin/ethlambda/assets/hoodi/config.yaml hoodi/metadata/config.yaml ``` ## Related Issues / PRs - Reverts the config half of #677 - Upstream: eth-clients/hoodi#33 ## ✅ Verification Checklist - [ ] Ran `make fmt` — n/a, no Rust changes - [ ] Ran `make lint` (clippy with `-D warnings`) — n/a, no Rust changes - [ ] Ran `make test` (`test-consensus` plus `test-node`, at `release-fast`) — ran `cargo test -p ethlambda --bins` only, the crate embedding the file
Motivation
Hoodi schedules Glamsterdam: Gloas activates at epoch 132352, fork version
0x80000910, at 2026-10-26 17:42:48 UTC (eth-clients/hoodi#31). Our built-in Hoodi config is eth-clients' file byte for byte, and our copy predates that PR.Picking up the new schedule exposed a second problem. A beacon resume compared the fork schedule for equality, so every existing Hoodi directory would have been refused (
ConfigChanged) the first time it started with the new config. Scheduling a fork always edits exactly those fields, after every node has already initialized its directory.Description
1. Hoodi config (
10eec50f)bin/ethlambda/assets/hoodi/config.yamlis copied again frometh-clients/hoodiatef89989:GLOAS_FORK_VERSION: 0x80000910,GLOAS_FORK_EPOCH: 132352MIN_BUILDER_WITHDRAWABILITY_DELAY,*_DUE_BPS_GLOAS,PAYLOAD_DUE_BPS,PAYLOAD_ATTESTATION_DUE_BPSCHURN_LIMIT_QUOTIENT_GLOAS,CONSOLIDATION_CHURN_LIMIT_QUOTIENT,MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT_GLOASMAX_REQUEST_PAYLOADSGAS_LIMIT_SCHEDULE(200M gas at the fork epoch)Every value except
GAS_LIMIT_SCHEDULEmatches the Gloas block Sepolia's config already carries, and the mainnet defaults a gloas build uses for an absent key.bootstrap_nodes.yamlalready matches upstream.On this branch the only visible effect is a longer ignored-keys warning. On a build that claims
GLOAS_*(#634 and up), this is what lets a Hoodi follower cross the fork.2. Resume across a fork scheduled ahead of the directory (
d182ae2b)first_config_differencetakesprocessed_through: the latest epoch the directory holds a block or state of. That is the highestLiveChainslot, or the finalized state's slot when it is later (a checkpoint-sync anchor advanced through empty slots).genesis_fork_versionchangedBLOB_SCHEDULEfollows the same rule: entries up toprocessed_throughmust match. Every other compared field is still compared for equality.Accepting the change is not enough on its own, because the node runs on the persisted config. A resume that passes now writes the config file over
Metadata["config"]with the newStore::replace_config, which panics unless itsStoreholds the only handle to the cached config, so a clone cannot go on serving the old one. As a result, the file's values (CONFIG_NAMEincluded) are what the node runs on and reports after a resume. Before, the stored values silently won for every uncompared field.Merging into the gloas stack
The yaml merges cleanly.
main.rsconflicts infirst_config_difference'scompare!list, where the gloas branches addgloas_fork_version/gloas_fork_epoch. Resolve it by taking this side and dropping those two lines: the per-fork loop walksForkName::ALL, which includes Gloas there. Keeping them incompare!would bring back the refusal.How to test
New tests:
a_resume_follows_a_fork_scheduled_ahead_of_the_directory(anchor with fulu unset, resume with it scheduled, check the new schedule is served and persisted),a_fork_schedule_may_change_only_ahead_of_what_was_processed,a_blob_schedule_entry_may_be_added_only_ahead_of_what_was_processed, and tworeplace_configtests in storage.a_resume_with_an_edited_config_names_the_field_that_changedused to move electra, which a genesis-anchored directory has not reached and which is now accepted. It now moves altair onto epoch 0.