Repository navigation
Derive default auth data from the builder hostname - #168
Merged
Merged
Conversation
nflaig
marked this pull request as ready for review
September 16, 2026 20:20
JasonVranek
reviewed
Sep 17, 2026
0w3n-d
approved these changes
Sep 17, 2026
0w3n-d
left a comment
There was a problem hiding this comment.
Looks good to me. I'm a fan of defaults like this.
JasonVranek
approved these changes
Sep 17, 2026
syjn99
approved these changes
Sep 18, 2026
3 of 4 tasks
StefanBratanov
approved these changes
Sep 18, 2026
mergify Bot
pushed a commit
to sigp/lighthouse
that referenced
this pull request
Sep 18, 2026
## Description Adds the per-validator builder configuration endpoints from [ethereum/keymanager-APIs#88](ethereum/keymanager-APIs#88). - `GET /eth/v1/validator/{pubkey}/builder_config` returns the configuration in use for the validator. - `POST /eth/v1/validator/{pubkey}/builder_config` replaces and persists the full configuration on a per-validator basis. It does not merge with the previous entry. - `DELETE /eth/v1/validator/{pubkey}/builder_config` removes the stored entry, so the validator inherits the global configuration again. The API stores per-validator entries under `validator_configs` in `builder_definitions.yml`. Changes made by `POST` and `DELETE` apply to subsequent builder preference publication and Gloas block production without a restart. When `auth_data` is omitted, global and per-validator builder configurations use the builder URL's lowercase ASCII hostname, following [ethereum/builder-specs#168](ethereum/builder-specs#168), [ethereum/beacon-APIs#642](ethereum/beacon-APIs#642) and [ethereum/keymanager-APIs#94](ethereum/keymanager-APIs#94). URLs with and without a trailing slash produce the same auth data. Closes #9796 Closes #10076 Co-authored-by: Mark Mackey <mark@sigmaprime.io>
ckoopmann
approved these changes
Sep 18, 2026
ckoopmann
left a comment
There was a problem hiding this comment.
Yes this would work for the ultrasound relay as well.
nflaig
added a commit
to ChainSafe/lodestar
that referenced
this pull request
Sep 18, 2026
Follows ethereum/builder-specs#168, an omitted `auth_data` of a builder entry is now the hostname of its url instead of the url bytes verbatim, so a trailing slash, an explicit default port or different casing no longer changes the signed bytes. buildoor still compares the url verbatim, so the builder-dev kurtosis setup fails auth until it follows the spec change.
Merged
2 tasks done
SamAg19
pushed a commit
to SamAg19/lighthouse
that referenced
this pull request
Sep 18, 2026
## Description Adds the per-validator builder configuration endpoints from [ethereum/keymanager-APIs#88](ethereum/keymanager-APIs#88). - `GET /eth/v1/validator/{pubkey}/builder_config` returns the configuration in use for the validator. - `POST /eth/v1/validator/{pubkey}/builder_config` replaces and persists the full configuration on a per-validator basis. It does not merge with the previous entry. - `DELETE /eth/v1/validator/{pubkey}/builder_config` removes the stored entry, so the validator inherits the global configuration again. The API stores per-validator entries under `validator_configs` in `builder_definitions.yml`. Changes made by `POST` and `DELETE` apply to subsequent builder preference publication and Gloas block production without a restart. When `auth_data` is omitted, global and per-validator builder configurations use the builder URL's lowercase ASCII hostname, following [ethereum/builder-specs#168](ethereum/builder-specs#168), [ethereum/beacon-APIs#642](ethereum/beacon-APIs#642) and [ethereum/keymanager-APIs#94](ethereum/keymanager-APIs#94). URLs with and without a trailing slash produce the same auth data. Closes sigp#9796 Closes sigp#10076 Co-authored-by: Mark Mackey <mark@sigmaprime.io>
nflaig
added a commit
to ethereum/keymanager-APIs
that referenced
this pull request
Sep 18, 2026
Aligns the `auth_data` default with ethereum/builder-specs#168, the builder's hostname instead of the URL bytes verbatim, and updates the examples accordingly.
nflaig
added a commit
to ethereum/beacon-APIs
that referenced
this pull request
Sep 18, 2026
Aligns the `data` default with ethereum/builder-specs#168, the builder's hostname instead of the URL bytes verbatim.
pull Bot
pushed a commit
to Hawthorne001/prysm
that referenced
this pull request
Sep 22, 2026
…nLabs#17511) **What type of PR is this?** > Feature **What does this PR do? Why is it needed?** - ethereum/builder-specs#168 Implements this spec change. **Which issue(s) does this PR fix?** N/A **Other notes for review** Note that using the current version of buildoor would probably have some trouble as buildoor is not yet updated (Nico already opened a [PR](ethpandaops/buildoor#192) for this). So I'd suggest to merge this PR **after** all open PRs are merged. **Acknowledgements** - [x] I have read [CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md). - [x] I have included a uniquely named [changelog fragment file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd). - [x] I have added a description with sufficient context for reviewers to understand this PR. - [ ] I have tested that my changes work as expected and I added a testing plan to the PR description (if applicable).
15 of 28 tasks
frisitano
added a commit
to eth-act/lighthouse
that referenced
this pull request
Oct 22, 2026
…025 (#54) * Avoid walking already indexed validators in the monitor (#9995) ## Issue Addressed The [validator monitor](https://github.com/sigp/lighthouse/blob/115bd16fb565c3df2b169a740fa5754adde00762/beacon_node/beacon_chain/src/validator_monitor.rs#L484-L502) walks the already indexed registry during recent block imports, including with default monitoring and zero monitored validators. Milhouse's `iter().skip(index)` traverses the skipped prefix even when there are no new validators. ## Proposed Changes Start the iterator at the first unknown index with `iter_from`, keeping absolute validator indices. A regression test covers empty registries, growth, shorter forks, late registration and pending updates for both fixed and progressive lists. ## Additional Info A local mainnet A/B on 7 Sep 2026 used two Lighthouse followers with separate mock ELs, zero monitored validators and a registry of about 2.36 million validators. Each follower had a 3-CPU quota on the same AMD EPYC-Milan VM. The builds used baseline `1256bd99`, with only this loop changed in the treatment. Each window followed one epoch of settling, with binaries swapped between nodes for the second window. | Median `import_block` duration | Baseline | Treatment | Matched blocks | | --- | ---: | ---: | ---: | | 19:29-19:43 UTC | 199.87 ms | 38.47 ms | 66 | | 19:53-20:07 UTC, after swap | 191.60 ms | 40.56 ms | 66 | One first-window trace was unmatched and excluded; baseline logs confirm that block was received and became head. All slow outliers are included. All 132 matched imports improved. Mean paired import savings were 159.70 ms and 152.68 ms; the monitor child span accounted for 158.24 ms and 150.67 ms respectively. This measures local import completion with simulated execution validity. The monitor runs under the fork-choice write lock, normally after early attestability. These results do not establish earlier attestations, whole-client CPU savings or the same absolute saving in production. * Remove buggy parent_root calculations from Gloas block production (#9997) ## Issue Addressed Gloas block production was calculating the parent_root twice, once before advancing the parent state and once after. The calculation prior to the state advance **would yield the wrong block root** in the case where the parent state was not already advanced. In practice, this didn't occur very often because the state advance timer would make the advanced state available in the state cache. https://github.com/sigp/lighthouse/blob/1256bd99e1b6c5d1290241849354b7e27dbc0ed9/beacon_node/beacon_chain/src/block_production/gloas.rs#L185-L191 This potentially incorrect block root was used to calculate `should_build_on_full` on the next line: https://github.com/sigp/lighthouse/blob/1256bd99e1b6c5d1290241849354b7e27dbc0ed9/beacon_node/beacon_chain/src/block_production/gloas.rs#L193-L199 As a result, we would sometimes end up reading `should_build_on_full` for the **grandparent** block rather than the parent. Often, this wouldn't make any difference. The impact of this bug was further mitigated by the fact that we re-calculated the `parent_root` a 2nd time _after_ the state advance: https://github.com/sigp/lighthouse/blob/1256bd99e1b6c5d1290241849354b7e27dbc0ed9/beacon_node/beacon_chain/src/block_production/gloas.rs#L378-L398 This `parent_root` would always be correct, so the block would always be valid, just possibly building on the wrong empty/full variant. ## Proposed Changes Calculating the `parent_root` at all is conceptually unnecessary. It was already decided and known when we called `load_state_for_block_production`. This PR threads that value through and removes both re-calculations. A regression test is added in `gloas_block_production_parent_root_with_unadvanced_state`. I've verified that it fails on unstable and passes with this patch. ## Additional Info Codex was used, but as you can see from the commit history, there was a lot of tweaking to arrive at the simplest fix. Some more refactors and cleanups are possible (e.g. removing ReOrgInputs), but I'll do that in a separate PR to avoid muddying this bugfix. This bug is similar to another one recently found in block prod. I'm going to try to weed them all out: - https://github.com/sigp/lighthouse/pull/9983 * Ignore exits for all withdrawing validators in Gloas block prod (#9983) ## Issue Addressed Closes: - https://github.com/sigp/lighthouse/issues/9981 ## Proposed Changes Filter out exits for validators which _could_ be impacted by any withdrawal triggered in the parent execution payload. See linked issue for details of the bug. This fix prevents production of invalid blocks (!!) in some scenarios post-Gloas. ## Additional Info Fix & comments written manually, tests fixed by Codex. Regression test by Codex with manual review. * Add attestations test with `payload_present` in op pool (#9531) Add a test in operation pool about the index for the cases with and without payload_present. Written with Claude Code and did a self review Currently blocked waiting for https://github.com/ethereum/consensus-specs/issues/5399 fix Update: the fix https://github.com/ethereum/consensus-specs/pull/5473 is merged and included in [v1.7.0-alpha.13](https://github.com/ethereum/consensus-specs/releases/tag/v1.7.0-alpha.13), currently pending for Lighthouse update to alpha 13 * Don't return Pending node when fork choice reverts to justified block (#9962) Closes #9544. ## Description - `find_head_walk` was filtering virtual EMPTY/FULL children of a PENDING node against `viable_nodes`. Under deep non-finality the justified seed can be non-viable, so those children were dropped and `get_head` returned Pending, which breaks block production. - Skip the filter for PENDING heads. Viability filtering still applies to real block children from EMPTY/FULL nodes. - Adds `pending_head_resolves_when_justified_subtree_non_viable` in `gloas_payload.rs`. * Fix flaky unknown block test (#10001) ## Issue Addressed Fix flaky CI test: - https://github.com/sigp/lighthouse/issues/9999 ## Proposed Changes The test was failing due to a race between importing the block on gossip vs importing the block as a result of its `getBlobs` call completing. The `getBlobs` codepath was missing a notification to the reprocess queue, which this PR adds. There's also a new test added which prevents regression on the `getBlobs` codepath. ## Additional Info Heavily Codex driven, manually reviewed. Change makes sense to me. * Gloas spec beta 0 (#10014) ## Issue Addressed Each commit has a link to the relevant consensus spec PR * Convert produceBlockV4 to POST and round-trip Eth-Builder-Url (Gloas builder API 4/5) (#9806) Fourth PR of the Gloas builder API stack (beacon-APIs #630): - convert `/eth/v4/validator/blocks/{slot}` to POST with an optional `BuilderConfig` body (min_bid, builder_boost_factor, direct builders) - add `POST /eth/v1/validator/builder_preferences` for forwarding signed builder preferences - set `Eth-Builder-Url` on produceBlockV4 responses when a direct-builder bid wins, accept it on `POST /eth/v2/beacon/blocks`, and forward the signed block to that builder The validator client still uses the legacy GET methods at this point; it migrates in the final PR of this stack. * `engine_getBlobsV4` (#9438) ## Issue Addressed Implement EIP-8070's engine API calls: `engine_getBlobsV4`. ## Additional Info Claude was heavily used for prototyping. Gloas support will be added after #9325 is merged. * Add 0x02 support to validator creation (#9702) ## Issue Addressed NA ## Proposed Changes Adds the `--compounding` flag to `lighthouse validator_manager create` to allow creation of validators with 0x02-prefixed withdrawal credentials. ## Additional Info I had to move some test vectors from Holesky to Hoodi as `ethstaker-deposit-cli` has stopped supporting Holesky. Co-authored-by: Tan Chee Keong <tanck@sigmaprime.io> * Standardise FCR metrics (#9987) ## Issue Addressed Closes #9663 ## Proposed Changes Adopt [beacon-metrics](https://github.com/ethereum/beacon-metrics/blob/master/metrics.md#fast-confirmation) | Standard metric | Was | Fires | |---|---|---| | `beacon_fast_confirmation_slot` | `beacon_fcr_confirmed_root_slot` | after each FCR run | | `beacon_fast_confirmation_reorgs_total` | new | head reorgs off a confirmed block | | `beacon_fast_confirmation_fallbacks_total` | `beacon_fcr_revert_to_finalized_total` | confirmed root reverts to finalized | | `beacon_fast_confirmation_restarts_total` | `beacon_fcr_restart_from_justified_total` | restart from the observed justified checkpoint | Added a metric to track head reorgs out of the previous confirmed root: - `_confirmed_root_reorgs_total` * Enable FCR test cases (#9964) ## Issue Addressed Enable remaining FCR test cases ## Proposed Changes Fix fake_crypto to produce correct states if the input pub keys are valid ## Additional Info * Cherry Pick Tolerate empty sync aggregates in the basic simulator (#9781) * Cherry Pick Attempt to fix flaky fallback simulator test (#9908) * Cherry Pick Update Docker builder to Debian Bookworm (#9984) * Cherry-pick lint fixes * broadcast PTC votes early on payload availability (#9434) - Updated PayloadAttestationService to broadcast PTC votes as soon as the execution payload and data columns are available (via SSE execution_payload_available event). - Retained the existing deadline as fallback. - Follows the same early-trigger pattern used by AttestationService. Addresses #9422 and #9584 Co-authored-by: Eitan Seri- Levi <eserilev@gmail.com> Co-authored-by: Eitan Seri-Levi <eserilev@ucsc.edu> Co-authored-by: Tan Chee Keong <tanck@sigmaprime.io> * Avoid copying unchanged justified balances (#10023) ## Issue Addressed - `find_head` clones `JustifiedBalances` on every call, even when it hasn't changed. - During block import, this copy happens while holding the fork choice write lock. ## Proposed Changes - Use the existing `PartialEq` implementation to only clone `JustifiedBalances` when it changes. ## Additional Info - An instrumented mainnet run with a mock EL found unchanged balances in **130 of 131 calls**, including all 33 block imports. - Tested against the parent commit with two mainnet beacon nodes in Kurtosis, using mock ELs and equal CPU and memory limits. Both stayed synced with matching block roots and finalized checkpoints. - Across **96 block imports per node**, average fork choice time during block import dropped from **31.58 ms to 15.00 ms**, about **53% lower**. This includes `get_head` and the early attester cache update. Both nodes ran on the same dev box. * Bump `rustls` to fix cargo audit failure (#10052) ## Issue Addressed Cargo audit failure from `rustls`: https://rustsec.org/advisories/RUSTSEC-2026-0285.html ## Proposed Changes Bump locked `rustls` version to `0.23.45` * Revert "Move `SlotAssignment` cache to `CanonicalHead` (#9661)" (#10047) ## Issue Addressed Per this comment: https://github.com/sigp/lighthouse/pull/9831#discussion_r3974642470, it turns out we don't need the `SlotAssignments` cache for regular fork choice. Attempting to use it in the general case is difficult because we need to deal with the fact that cache may be stale, and that building it while holding a lock could be very slow. This PR reverts dbd2824326af23655a9e50b75046a29739203dac so that the cache is used ONLY for FCR. ## Proposed Changes Reverted the commit dbd2824326af23655a9e50b75046a29739203dac and resolved conflicts in `beacon_node/beacon_chain/src/canonical_head.rs` mostly relating to the fork choice poisoning (unrelated changes on nearby lines). ## Additional Info Codex used for conflict res, results checked manually. * fork choice compliance tests (#9710) ## Issue Addressed Add consensus spec fork choice compliance tests Some tweaks were made to get tests passing: 1. For attestation related tests: If attestations are for a future-slot and queued we treat them as import failed. 2. Updated test runners to recompute head before every block import 3. Blocks rejected by block verification instead of fork choice skip fork-choice assertions. 4. We don't re-import block attestations after `on_block`. Lighthouse block import already does this, but via the from-block path, which skips the `validate_target_epoch_against_current_time` validation step 5. We only run complaince tests for fake_crypto + fulu/gloas minimal * Add base support for Heze block production (#9714) ## Proposed Changes - Enable Heze block production by constructing `BeaconBlockHeze` in `complete_partial_beacon_block_gloas` (the body is identical to the Gloas beacon block variant) - This work is a pre-requisite for testing the upcoming FOCIL PRs - Route Heze block building through the existing Gloas `getPayload` path, because the [engine API spec for Bogota](https://github.com/ethereum/execution-apis/blob/main/src/engine/bogota.md) defines no new `getPayload` version for this fork. Heze responses are deliberately deserialized into the Gloas containers (see [TODO added](https://github.com/sigp/lighthouse/pull/9714/changes#diff-8b79597c7e1a33167a01f676e50f09dbc40e761dad5b294086ebda40828e1641R1064-R1065)), so the Heze-specific engine types stay unused until the payloads diverge. Likewise, envelope submission still uses the Gloas `newPayloadV5` path - Add test producing and importing blocks across the Heze boundary epoch This PR unblocks Heze testing through the beacon chain harness. Previously, with block production stubbed, the harness could not build or advance a Heze chain. This is a blocker for any Heze integration tests, a prerequisite for the upcoming FOCIL PRs' tests. * Cache slashed justified balances (#9830) ## Issue Addressed This PR caches slashed justified balances so that we can later use these values in gloas's is_head_weak. Since BalancesCache is not persisted to disk, its superstruct variants and encode/decode implementations are no longer necessary. Instead of storing a vec of balances in the cache, we store JustifiedBalances directly in memory, which also contains the slashed validator balances. Previously slashed validator balances were zeroed out. Now we add an extra field that keeps track of slashed balances. There is a bit of a gap here that I don't think is worth fixing: A validator slashed between justfied epoch and current epoch balance wont be recorded as a slashed validator in this cache, that is their value will stil be recorded in the normal balances map, but not in the slashed balances map. These values are only recorded at justification. Also valdiators activated after the justified epoch dont show up in this cache as well. This is a slight deviation from the spec, as the spec reads raw state balances. Its a very minor edge case and I don't think its worth worrying about. * Add support for engine_forkchoiceUpdatedV5 (#9935) ## Issue Addressed Part of the FOCIL implementation. This PR adds the `engine_forkchoiceUpdatedV5` ([execution api spec](https://github.com/ethereum/execution-apis/blob/main/src/engine/bogota.md#engine_forkchoiceupdatedv5)) engine API integration, which enables specifying an inclusion list to the execution client when requesting a payload to be built. ## Proposed Changes - Add `PayloadAttributesV5`, which extends V4 with `inclusion_list_transactions` ([spec](https://github.com/ethereum/execution-apis/blob/main/src/engine/bogota.md#payloadattributesv5)) - Add `engine_forkchoiceUpdatedV5` support to the engine API module and expose the capability through `exchange_capabilities` - Handle the response's `PayloadStatusV2`, which appends the `inclusionListSatisfied` field (per [spec](https://github.com/ethereum/execution-apis/blob/main/src/engine/bogota.md#payloadstatusv2)) - Send V5 attributes for Heze slots. Note that `custody_columns` is sent as null, matching [the consensus specs](https://github.com/ethereum/consensus-specs/blob/master/specs/heze/validator.md#L184-L190) - Add mock execution engine support, rejecting V4 attributes from Heze onwards - Add Heze boundary tests for preparing a payload, checking if the fcU request that the mock receives is the expected one ## Additional Info - `inclusion_list_transactions` is sent empty for now; populating it from the inclusion list store will be added in a follow-up PR * Fix Gloas nodes failing to resume sync after restart (#9940) ## Description After a restart, a Lighthouse node can fail to resume syncing on a Gloas network. This can happen when the node persists a Gloas beacon block before it fully imports the payload envelope. A restart then clears the in-memory pending payload cache. Sync downloads the envelope and custody columns for the block again, but reprocessing the known block does not restore its signed execution payload bid. Lighthouse cannot join the downloaded components, and the lookup can run out of attempts. Dependent blocks then stop progressing. Custody-column and execution-proof processing now load the bid from the persisted block when the cache is empty. Envelope processing reuses the bid from the block that it already loaded. * Wire the inclusion list store into BeaconChain (#9960) ## Issue Addressed Part of FOCIL (EIP-7805). This puts the inclusion list store from #9744 onto `BeaconChain` and adds the read wrappers that will be used by gossip verification, fork-choice enforcement, and block production. ## Proposed Changes * Add an `inclusion_list_store` field to `BeaconChain`, initialise it from `ChainSpec` in `builder.rs`, and prune it in `per_slot_task`. * Add `inclusion_list_committee`, which resolves the ordered committee for a slot and returns it together with the dependent root used to key the store. * Add `get_inclusion_list_transactions`, `get_inclusion_list_bits`, and `is_inclusion_list_bits_inclusive` as wrappers around the store reads. * Add `BeaconChainError::InclusionListStoreError`. * Add tests covering each read path, the epoch boundary case, and pruning through `per_slot_task`. This is independent of #9846, and nothing is calling these wrappers yet. Gossip verification will be the follow-up. ## Additional Info The wrappers take an anchor block root rather than using the head. `with_committee_cache` only resolves a block's own or next epoch shuffling, while inclusion list reads use `slot - 1`. Once per epoch, that falls into the previous epoch and fails when using the head root. There's a test covering this case. `with_committee_cache` already gives us the attester shuffling decision root, so we get both the committee and the store key from the same lookup. This is also the root that the producer puts in the message as `dependent_root`. `get_inclusion_list_transactions` only needs to resolve the shuffling for the dependent root and then discards the committee, since that root comes out of the same lookup. Co-authored-by: Eitan Seri- Levi <eserilev@gmail.com> * Add support for engine_newPayloadV6 (#10017) ## Issue Addressed Part of FOCIL (EIP-7805). This adds `engine_newPayloadV6`, as specified in [Bogota](https://github.com/ethereum/execution-apis/blob/main/src/engine/bogota.md). ## Proposed Changes * Add `ENGINE_NEW_PAYLOAD_V6` and the `new_payload_v6` capability. * Add `inclusion_list_transactions` to `NewPayloadRequestHeze`. * Add `new_payload_v6_heze` and dispatch Heze requests to it. * Add `inclusion_list_satisfied` to `PayloadStatusV1` for the new `inclusionListSatisfied` response field. * Route the method in the mock EL, and fix its Heze fork check, which required V5. * Add tests for deserialising the response with and without `inclusionListSatisfied`. Nothing constructs a `NewPayloadRequestHeze` yet, so this doesn't change any behaviour. I also cleaned up the two now stale `TODO(heze)`s. ## Additional Info I kept `inclusion_list_satisfied` on `PayloadStatusV1` rather than introducing a `PayloadStatusV2`. The new field is `BOOLEAN|null`, and the existing fields already use `Option` for the same reason. The alternative would be to introduce a versioned superstruct like `PayloadAttributes`, but that would mean making changes outside `execution_layer`. I'm fine with going that way if that's preferred. The Heze arm in `payload_notifier.rs` will need the transactions from the store. That part follows once #9960 merges. * Migrate the validator client to the Gloas builder API (Gloas builder API 5/5) (#9807) Final PR of the Gloas builder API stack: - sign builder request-auth and preferences (REQUEST_AUTH signing domain, web3signer message type) - add the builder configuration store (`builder_definitions.yml`) and book documentation - add the builder-preferences service and switch block production to `POST` produceBlockV4 with a `BuilderConfig` body, threading the `Eth-Builder-Url` header through block publication - remove the now-unused legacy `GET` produceBlockV4 client methods * Add per-validator builder configuration API (#9864) ## Description Adds the per-validator builder configuration endpoints from [ethereum/keymanager-APIs#88](https://github.com/ethereum/keymanager-APIs/pull/88). - `GET /eth/v1/validator/{pubkey}/builder_config` returns the configuration in use for the validator. - `POST /eth/v1/validator/{pubkey}/builder_config` replaces and persists the full configuration on a per-validator basis. It does not merge with the previous entry. - `DELETE /eth/v1/validator/{pubkey}/builder_config` removes the stored entry, so the validator inherits the global configuration again. The API stores per-validator entries under `validator_configs` in `builder_definitions.yml`. Changes made by `POST` and `DELETE` apply to subsequent builder preference publication and Gloas block production without a restart. When `auth_data` is omitted, global and per-validator builder configurations use the builder URL's lowercase ASCII hostname, following [ethereum/builder-specs#168](https://github.com/ethereum/builder-specs/pull/168), [ethereum/beacon-APIs#642](https://github.com/ethereum/beacon-APIs/pull/642) and [ethereum/keymanager-APIs#94](https://github.com/ethereum/keymanager-APIs/pull/94). URLs with and without a trailing slash produce the same auth data. Closes #9796 Closes #10076 Co-authored-by: Mark Mackey <mark@sigmaprime.io> * Replace EF bootnodes with NodeOps fleet (#10025) I am on the Ethereum Foundation's Node Infrastructure team (NodeOps). We run the bootnodes that ship in this repository as the "EF" entries for mainnet, Sepolia and Hoodi. We are replacing that fleet, and we would like the new records in a release before the Glamsterdam client releases. ### What changes - Add five new EF bootnodes per network. Every node serves all three networks. - Remove the legacy EF entries. The new set is a replacement, not an addition. - Third-party bootnodes and DNS discovery roots are untouched. ### The new fleet Five bootnodes, each serving mainnet, Sepolia and Hoodi. They are geographically distributed, multi-cloud, and dual stack (IPv4 + IPv6). Each node runs discv4 and discv5 on the EL port and discv5 on the CL port, and the fleet spreads across several discovery implementations so one implementation bug cannot take the whole set down. ### About the records - The ENRs are generic bootnode records: no `eth2` field, no `tcp`, sequence number 1. Clients dial configured bootnodes regardless of fork, and a static list cannot be re-signed every fork, so we do not include fork data on purpose. - Where an EL list accepts ENRs, we list the ENR. It covers discv4 and discv5 and carries the IPv6 endpoint. Enodes appear only where a list needs them, in the discovery-only form `enode://<pubkey>@<ip>:0?discport=<port>` (no RLPx listener). - The records are derived from the node keys and are byte-identical across all the client PRs. The canonical copies are the eth-clients PRs (`metadata/bootstrap_nodes.yaml` and `metadata/enodes.yaml` for mainnet, sepolia and hoodi). ### Verification - Each node answers discv4 and discv5 pings from the public internet on the advertised ports. - The relevant tests in this repository pass with the new lists (details below). - The legacy nodes stay online until client releases with the new records are widely deployed. We will announce the shutdown separately. ### Contact Chase Wright, EF Node Infrastructure. Discord `MysticRyuujin` (ETH R&D and STEEL servers), or chase.wright@ethereum.org. ### This repository **Files:** `common/eth2_network_config/built_in_network_configs/{mainnet,sepolia,hoodi}/bootstrap_nodes.yaml`. **Semantics:** the EF ENRs (4 / 5 / 6) are replaced by the five new CL ENRs per network. **Tests:** `cargo test -p eth2_network_config` (decodes every built-in ENR). * Add license/cla check in mergify (#10049) If an author does not sign CLA, the PR will be marked as `ready-for-review` (if all other tests passed). Example: https://github.com/sigp/lighthouse/pull/10043 Add a condition to check that if the author has not signed CLA, it is marked as `waiting-on-author`. * enable mplex by default (#10070) * engine_forkchoiceUpdatedV4: provide custody columns to the EL (#9547) ## Issue Addressed [engine_forkchoiceUpdatedV4 supplies the custody columns to the EL so that the EL client can employ a sparse blobpool.](https://github.com/ethereum/execution-apis/blob/main/src/engine/amsterdam.md#request-4) ## Proposed Changes Send the current custody columns to the EL on every regular `engine_forkchoiceUpdatedV4` Co-authored-by: Pawan Dhananjay <pawandhananjay@gmail.com> * update: chiado bootnodes enrs (#9923) ## Description Update `Chiado` bootnode enrs. * Fix custody backfill N× DataColumnsByRange amplification (#10048) ## Summary - Fix custody backfill sending the full `DataColumnsByRange` request to every selected peer (N× download amplification). - Select peers using `request.columns` instead of the wider sampling set. - Add regression tests for per-peer column subsets and request-vs-sampling peer selection. Closes #10045 ## Test plan - [x] `FORK_NAME=fulu cargo nextest run -p network custody_backfill` Co-authored-by: Eitan Seri-Levi <eserilev@ucsc.edu> * Document won't-fix vote slot reset in V28 to V29 migration (#10108) ## Issue Addressed shut up LLMs about it * Fix gossip bid rejection at epoch boundaries and on the head's parent (#10061) ## Issue Addressed Valid payload bids can be dropped with `EpochOutOfBounds` when the cached head is from the previous epoch. Bids on the head's parent can also be rejected with `InvalidPrevRandao` because validation uses the head's RANDAO mix. ## Proposed Changes Validate `prev_randao` against the bid's beacon parent using the existing `head_random` and `parent_random` helpers. Add a regression for a head in the previous epoch. Head-parent RANDAO spec coverage is tracked in [consensus-specs#5645](https://github.com/ethereum/consensus-specs/pull/5645). ## Additional Info The [Gloas gossip rule](https://github.com/ethereum/consensus-specs/blob/a8475719ce77cb269191e327e1f4175c295851ee/specs/gloas/p2p-interface.md#execution_payload_bid) uses the parent post-state's current epoch. Related to #9924. * Gloas spec v1.7.0-beta.2 (#10114) ## Issue Addressed Latest spec release and tests. ## Additional Info Codex used, all code manually reviewed. Co-authored-by: Lion - dapplion <35266934+dapplion@users.noreply.github.com> Co-authored-by: Pawan Dhananjay <pawandhananjay@gmail.com> * Route fork-choice execution status through fork choice nodes (#10100) ## Issue Addressed This is a pre-step to add gloas optimistic sync. Improper execution status reading on gloas nodes, on empty descendants of invalid. ## Proposed changes Fork-choice execution-status queries took a bare root and answered about the block's `FULL` node. In the two-node (Gloas) model an `EMPTY` head runs an ancestor's payload, so an empty head could report a validity its branch never ran. - Add `ForkChoiceNode` (opaque root + payload status) and `ExecutionVerdict` (no payload hash). - Split the query w/ node-aware `get_node_execution_status(node)` vs `get_block_execution_status_assuming_full(root)`. - Gate attesting/proposing on the actual node (attester/proposer duties, `produce_unaggregated_attestation`, `filter_optimistic_attestation`); assume-`FULL` stays only where there is no node (http_api `execution_optimistic`, sync-committee contributions, `is_healthy`). V29 (Gloas) execution status isn't tracked yet. Hardcoded `Valid` (`TODO(gloas)`) until the optimistic-payload work adds it. * Add stateless Gloas block production to the VC (#10036) ## Issue Addressed #8828 (VC half; the beacon-node half landed in #9568) ## Proposed Changes Add `--stateless-block-production` (default off). When set, the VC produces Gloas blocks with `include_payload=true`, keeps the returned envelope, blobs and KZG proofs, and after publishing the block signs that envelope and publishes it as `SignedExecutionPayloadEnvelopeContents` through the same node selection as the block. This removes the per-BN envelope cache dependency: the envelope is never fetched, and any beacon node can accept the contents form. - `ValidatorStore::sign_block` gains `local_payload_root: Option<Hash256>`, the `hash_tree_root` of the locally built payload. Lighthouse's store ignores it. - With the flag off, behaviour is unchanged. ## Additional Info `ValidatorStore` is also implemented by DVT clients (e.g. Anchor), where the proposer must commit to its payload root before the block is agreed, which is why the root is passed into `sign_block` rather than derived after publication. Based on #9807; will retarget `unstable` once it merges. Verified with `cargo nextest run -p validator_services -p validator_client -p lighthouse_validator_store -p validator_test_rig -p validator_store -p eth2`, `cargo nextest run --release -p lighthouse --test lighthouse_tests validator_client`, `make lint`, and `make cli-local`. * Add gas limit schedule (#9878) ## Issue Addressed https://github.com/ethereum/consensus-specs/pull/5533 * Introduce ParentPayloadStatus for the parent payload edge (#10121) ## Issue Addressed - New enum introduced by https://github.com/sigp/lighthouse/pull/9934 that we can merge ahead of time Current code silently defaults the gloas fork block parent into either empty or full. This makes the logic of #9934 harder to reason about ## Proposed Changes Make that edge case explicit and force consumers to make a choice. * Remove perfidious fn ExecutionStatus::block_hash (#10126) ## Issue Addressed While implementing Gloas optimistic sync this function `ExecutionStatus::block_hash` has been a cause of confusion and bugs. In unstable a None means either PreMerge of PostGloas, and some code uses it as a fork gate. ## Proposed Changes - Remove `ExecutionStatus::block_hash` for `Block::block_hash` with a clear return type `PayloadBlockHash` - Add `PayloadBlockHash` which makes it explicit that the return is only None for PreMerge * Remove ExecutionStatus predicates with no production callers (#10129) ## Issue Addressed Make #9934 easier to reason about, no need to map `NotYetRevealed` to anything in prod ## Proposed Changes Remove ExecutionStatus predicates with no production callers * Mark the forkchoiceUpdated head hash valid, not the head block (#10131) Extracted pre-step from https://github.com/sigp/lighthouse/pull/9934 ## Issue Addressed After Gloas validating by block_root is wrong if the head is empty, the EL judges the payload. It's correct and easier to reason about to tell fork-choice which block_hash the EL validated, same as https://github.com/sigp/lighthouse/pull/10130 ## Proposed Changes A VALID forkchoiceUpdated vouches for head_hash, which for a Gloas head on its EMPTY node is an ancestor's payload — so mark the hash valid, not the head block. on_valid_execution_payload(head_hash) resolves every committing node and runs the existing walk; V17 identical, equivocating twins now also promoted, Gloas nodes still a no-op. * Name invalidated payloads by execution block hash, not by block root (#10130) Extracted pre-step from #9934 ## Issue Addressed After Gloas invalidating by block_root is wrong if the head is empty, the EL judges the payload. It's correct and easier to reason about to tell fork-choice which block_hash the EL invalidated. ## Proposed Changes The EL judges payloads, so InvalidationOperation now names them by execution block hash and applies to every block committing to the judged payload (equivocation-safe). The two-step walk becomes find_deepest_node_to_invalidate / find_deepest_executed_node / invalidate_node_and_descendants; V17 behavior is preserved case-for-case, Gloas nodes are swept through unmarked as today (#9934 adds their status). notify_new_payload drops its root param and invalidates from the rejected payload's parent hash, which unifies the block and envelope callers. * Replay votes through compute_deltas when resetting to optimistic (#10133) ## Issue Addressed `set_all_blocks_to_optimistic` reimplements sensitive logic from `compute_deltas` and `apply_score_changes`, making #9934 more difficult to implement. ## Proposed Changes Just re-use `compute_deltas` and `apply_score_changes` instead of hand-rolling weight propagation. Co-authored-by: Michael Sproul <michael@sigmaprime.io> * Apply Beacon API amendments to payload attestation data endpoint (#9959) ## Issue Addressed Addressed the following 2 checklist items in #9045 - Amended GET `/eth/v1/validator/payload_attestation_data/{slot}` to use query instead of path - Amended GET `/eth/v1/validator/payload_attestation_data/{slot}` to return 204 when no block ## Proposed Changes - Commit https://github.com/sigp/lighthouse/commit/5bb8f47e06e034085cac2996fe67b275c182a071 : The endpoint `validator/payload_attestation_data/` returns 204 incase of an empty block for the slot in accordance to the spec changes mentioned in [beacon-APIs#612](https://github.com/ethereum/beacon-APIs/pull/612). `BlockNotFound` rejection has been removed since it was unused after the change and the `BeaconNodeHttpClient` maps 204 to `None` instead of 404. - Commit https://github.com/sigp/lighthouse/commit/9eb3912ef75b843bbfa43d6a791709d221e421c5 : `slot` moves from path to a query parameter for the endpoint in accordance to the spec changes mentioned [beacon-APIs#626](https://github.com/ethereum/beacon-APIs/pull/626) * Eagerly sign sync committee messages on head events (#9675) ## Proposed Changes `SyncCommitteeService` currently waits for the sync message due point every slot, even when the head block arrived seconds earlier. Per the [Altair honest validator spec](https://github.com/ethereum/consensus-specs/blob/master/specs/altair/validator.md#prepare-sync-committee-message), a sync committee member should produce the message "either when (a) the validator has received a valid block from the expected block proposer for the current `slot` or (b) `get_sync_message_due_ms()` milliseconds has transpired since the start of the slot", whichever comes first. This applies the head-event trigger that #7892 added for attestations to sync committee messages: - `sync_committee_service` races a head event against its due timer. Head-triggered slots sign the event's block root (the head monitor only forwards non-optimistic heads) and publish shortly after block arrival instead of at the due point. - Wires `SYNC_MESSAGE_DUE_BPS_GLOAS = 2500` ([Gloas time parameters](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/validator.md#time-parameters)) into `ChainSpec` with a fork-aware `get_sync_message_due_at_slot`, so the timer fallback tightens to 25% of the slot at Gloas. - Converts head events from mpsc to `tokio::broadcast` with `BeaconNodeFallback::subscribe_to_head_events()` so both services can consume them. The shared `head_event_or_deadline` helper also fixes a busy-spin in the attestation service when the head event channel closes. - Adds sync committee endpoints to `MockBeaconNode` and service tests on the shared VC harness. ## Additional Info N/A ## AI Assistance Disclosure **Tools used**: Claude Code Fable 5 * Notify reprocessing queue after RPC custody column imports (#10128) ## Issue Addressed An RPC-fetched payload envelope can complete execution verification while remaining pending on custody columns. When RPC custody columns subsequently complete the import, `process_rpc_custody_columns` recomputes the head but does not notify the reprocessing queue. As a result, attestations waiting for the payload envelope are not released by this import event and can remain queued until the existing fallback runs. The same RPC completion branch also handles pre-Gloas block imports. ## Proposed Changes Call the existing `notify_import_after_column` helper after successful import and head recomputation, using the slot and root returned by `AvailabilityProcessingStatus::Imported`. This matches the existing gossip column completion paths and emits the appropriate event: - `PayloadEnvelopeImported` for Gloas. - `BlockImported` for pre-Gloas. Add regression tests covering deferred envelope import under Gloas and deferred block import under Fulu. The tests check the event type and root, with no additional event in each tested sequence. The Gloas test also checks that no completion event is emitted while the envelope is still awaiting columns. ## Additional Info Both new regression tests failed before the production change and passed afterward: ```bash FORK_NAME=gloas cargo test --release -p network \ --features fork_from_env \ rpc_columns_notify_after_deferred_envelope_import FORK_NAME=fulu cargo test --release -p network \ --features fork_from_env \ rpc_columns_notify_after_deferred_block_import ``` The existing `release_awaiting_attestations_on_payload_envelope_imported` consumer test also passed. These tests cover the network processor notification and queue consumer separately; they are not a full network E2E test. AI assistance was used for the regression tests, and this PR description. * Use block hash in payload invalidation tests (#10137) ## Issue Addressed Continuation of the ideas in: - https://github.com/sigp/lighthouse/pull/10130 - https://github.com/sigp/lighthouse/pull/10131 ## Proposed Changes This PR applies block_hash-ification to all payload invalidation tests, preparing for Gloas tests and Gloas optimistic sync. ## Additional Info Codex wrote the code, I checked it. * GET `/eth/v1/validator/{pubkey}/graffiti` to return String instead of hex string (#10117) @yorickdowne reported a bug in Lighthouse KeyManager API where the GET graffiti endpoint is returning a hex string: https://discord.com/channels/605577013327167508/605577013331361793/1552293386646724652 This PR fixes it to return String. Thanks for the report. Testing result: Before: ``` { "data": { "pubkey": "0xab", "graffiti": "0x7465000000000000000000000000000000000000000000000000000000000000" } } ``` After: ``` { "data": { "pubkey": "0xab", "graffiti": "te" } } ``` * Enable partial data columns by default on all networks (#9896) ## Proposed Changes Enable partial data columns by default on all networks. ## Additional Info Partial data columns have been tested on Hoodi and Sepolia for quite some time now, and have shown to be advantageous. There have been no reports of reduced performance. * Progressive list type-level limits (#10106) ## Issue Addressed Trying to solve ProgressiveList DoS vectors. ## Proposed Changes Go back to type-level limits like before, using: - https://github.com/sigp/ssz_types/pull/86 ## Additional Info Several imperfections we still need to solve: - [ ] There's no bound on transactions and we probably need a spec change to safely add one (related: https://github.com/ethereum/consensus-specs/pull/5642#discussion_r4056618820) - [x] The upstream `ssz_types` initially only enforced the limits in some places. I've now changed it to enforce them everywhere to avoid oversized lists slipping through. For example `ProgressiveVariableList::try_from_iter` didn't enforce the limit but was reachable from indexed attestation JSON decoding (via `quoted_u64_var_list`). See: https://github.com/sigp/ssz_types/pull/86#discussion_r4068836679. Co-authored-by: Pawan Dhananjay <pawandhananjay@gmail.com> * Work around libp2p derive warning on Rust 1.100 (#10153) Fix CI for new changes in the beta compiler which more aggressively flag unreachable code: Example CI failure: - https://github.com/sigp/lighthouse/actions/runs/36512785758/job/109228438187?pr=9934 Upstream libp2p issue: - https://github.com/libp2p/rust-libp2p/issues/6600 * Re-enable optimistic sync for Gloas payload envelopes (#9934) ## Breaking change Can we force existing Gloas nodes to resync when updating to this new version? Then we can simplify the migrations as the property `execution_status` has continuity in mainnet from Fulu to Gloas. Otherwise there's an awkward partial disappearance between v29 and v30. ## Issue Addressed Re-enable optimistic sync for Gloas payload envelopes ## Proposed Changes Track the status of the payload (FULL) node in ProtoNode::execution_status Co-authored-by: Michael Sproul <michael@sigmaprime.io> * Update tests to be spec agnostic (#10051) ## Issue Addressed Certain tests are written with assumptions about Mainnet preset constants. This works fine when we hard code the spec we use for testing ( such as `let spec = ChainSpec::mainnet()`), but if we decide to switch to compile-time preset selection (by adopting something like #9229), these tests will needlessly fail when run under minimal. ## Proposed Changes Update offending tests to remove baked-in mainnet constant assumptions, making them spec agnostic. ## Additional Info This PR will be the first in a series of PRs made in an attempt to shrink the diff size of #9229 to make it more manageable to review. * Prune finalised payload envelopes (#10015) ## Issue Addressed Closes #9527. ## Summary This PR reduces beacon-node storage requirements after Gloas by splitting each `SignedExecutionPayloadEnvelope` into: - a persistent `SignedExecutionPayloadEnvelopeSummary`; and - a prunable `ExecutionPayloadGloas` body. Once a canonical block is finalized, Lighthouse retains the summary and removes the payload body. If the complete envelope is requested later, Lighthouse reconstructs it using the retained summary and the payload body returned by the EL through `engine_getPayloadBodiesByHashV2`. ## Implementation Slight adjustments were made to `SignedExecutionPayloadEnvelopeSummary` to reduce the calls made to EL, this involved adding the `ExecutionPayloadHeaderGloas` to the summary. * Keep fork choice finalized checkpoint consistent with split (#10165) ## Issue Addressed Closes: - https://github.com/sigp/lighthouse/issues/10142 ## Proposed Changes Simple fix to ensure fork choice's finalized checkpoint remains ahead of the on-disk `split`. We just need to persist fork choice in `after_finalization` prior to running the migration which advances the split. I think this is a simple and intuitive fix. ## Additional Info Two further changes which aren't essential but nice to have: - [x] A new database invariant stating that the persisted fork choice finalized checkpoint remains ahead of the split (f76ebc26689c1b8abe8d07c14201b7aa81abecc2). - [x] Try to prevent manual finalization (which breaks the invariant) from causing a startup failure by disabling the endpoint when FCR is enabled. This is imperfect protection because someone could enable FCR after running manual finalization, but it is what it is. Issue here for a more thorough fix: https://github.com/sigp/lighthouse/issues/10166. * Wire the inclusion_list gossip topic (#9846) ## Issue Addressed Part of FOCIL (EIP-7805). Adds the `inclusion_list` gossip topic so Heze nodes subscribe to it and route messages into the beacon processor. ## Proposed Changes - `GossipKind::InclusionList` and the `inclusion_list` topic, subscribed via `core_topics_to_subscribe` when `heze_enabled()`. - `PubsubMessage::InclusionList` with SSZ encode/decode, plus the gossip cache and whitelist filter entries. - `Work::GossipInclusionList` and its beacon processor queue, and the router arm that dispatches to it. ## Additional Info Gossip verification isn't in yet, so for now `process_gossip_inclusion_list` ignores every message and nothing gets forwarded. That lands in a follow-up. I went with `Box` rather than `Arc` here because the inclusion list store takes ownership of the `SignedInclusionList`. There's no decode size guard and no configured gossip cache timeout, same as the existing Gloas topics. `MAX_SIGNED_INCLUSION_LIST_SIZE` isn't in the tree yet and it belongs with the req/resp work anyway. * Restore transitive schema migration code (#10170) ## Proposed Changes It was impossible to upgrade v29 -> v31 because this code to do migrations one at a time was deleted ( :sweat_smile: by me in https://github.com/sigp/lighthouse/pull/9031). This PR puts it back. In future if we clean up migrations we should make sure to keep it. No test changes for now because we just need this ASAP. * Bump quinn * Fix FCR restart UX bug (#10160) ## Issue Addressed When a node restarts it's confirmed root reverts to finalized. This doesn't mean the head will ever re-org out of a confirmed root, but from the POV of the EL it looks like a reversion of FCR. ## Proposed Changes Impl https://github.com/ethereum/consensus-specs/pull/5673 spec to load the latest confirmed_root from disk. Fixes the issue from above. Still the confirmed_root can backtrack due to an error or the node losing sync. **just for metrics**, we keep track of the deepest confirmed root and watch head re-orgs from it. * Release v8.2.3 * Release v8.3.0-rc.0 * Simplify fork boilerplate (#10164) ## Proposed Changes _Anti-boilerplate LLM goes brrr_ Superstruct has macros for avoiding explicit `match` boilerplate, this PR applies them in a bunch of places where they previously weren't used. In addition, it uses fork-generic methods (like `SignedBeaconBlock::from_ssz_bytes_by_fork`) in place of fork-specific methods (like `SignedBeaconBlock{ForkName}::from_ssz_bytes`). The goal is to reduce the amount of line churn when adding a new fork variant, which may also simplify the implementation of some planned code-generator changes. * Add IL committee duties polling to the VC (#9799) ## Issue Addressed This PR adds polling of inclusion list committee duties to the VC per [spec](https://github.com/ethereum/consensus-specs/blob/master/specs/heze/validator.md#lookahead). This is part of adding FOCIL support in the Heze fork. ## Proposed Changes - Update `duties_service` to spawn a dedicated IL duties polling task. This only spawns when the Heze fork is scheduled. - The task polls IL committee duties for the current and next epoch, each slot, starting with `heze_fork_epoch - 1` epoch. - Note that this PR uses the same bandwidth optimization as attester/PTC polling: per epoch, it does a small request for one validator, only refetching the full duties list if the `dependent_root` is different than the cached one. - Duties are cached per epoch, together with the `dependent_root` they were computed against, and they are fully replaced when the dependent root changes. - The request to the BN is done through `POST validator/duties/inclusion_list/{epoch}`, per [beacon api spec](https://github.com/ethereum/beacon-APIs/pull/490/changes#diff-ceb4d08d1cb30c34a9a58b27ad023c417ed6eb3c35235c5848c67039e5403fc0R1-R71). - Included metrics: fetch/store/per-epoch timers, IL committee validators count gauge. ## Additional Info - The BN endpoint support will be added in a follow-up PR, since its addition depends on [PR #9742](https://github.com/sigp/lighthouse/pull/9742) (committee derivation) and [PR #9714](https://github.com/sigp/lighthouse/pull/9714) (Heze block production, needed for the testing setup). * Keep ENR next_fork_version at a BPO fork (#10161) ## Issue Addressed The ENR `eth2` field advertises the wrong `next_fork_version` when a BPO fork is scheduled before the next regular fork. The [Fulu p2p spec](https://github.com/ethereum/consensus-specs/blob/82b6e507dc31f6f7052e79b16ecfe3778c1b38f6/specs/fulu/p2p-interface.md#eth2-field) says that `next_fork_version` "will only change for regular forks, _not BPO forks_". `next_fork_epoch` counts BPO forks. `enr_fork_id` takes `next_fork_epoch` from `next_digest_epoch`, which includes BPO forks. But it takes `next_fork_version` from the next regular fork. Example: the current fork is Fulu, with a BPO fork at epoch A and Gloas at epoch B > A. Lighthouse advertises (Gloas, A). The spec requires (Fulu, A). Prysm's discv5 dial filter (`compareForkENR`, from OffchainLabs/prysm#15604) rejects a peer when `next_fork_epoch` matches and `next_fork_version` does not. Prysm advertises (Fulu, A). So in this window, Prysm does not dial Lighthouse nodes that it finds through discovery. No public network is in this state today. Spec issue: ethereum/consensus-specs#5701 ## Proposed Changes - `next_fork_version` is now the fork version in effect at `next_digest_epoch`. If nothing is scheduled, it is the current fork version. A fork epoch at `far_future_epoch` counts as not scheduled. - Add `enr_fork_id_next_fork_with_bpo`. It checks both fields for these cases: a BPO before, at, and after Gloas, a BPO only, nothing scheduled, a past BPO, pre-Fulu, and Gloas at `u64::MAX`. ## Additional Info - Before Fulu, `next_digest_epoch` returns the next regular fork's epoch. The result changes only when two regular forks share that epoch, for example Fulu and Gloas at the same epoch. It is then the later fork's version, which is the version in effect at that epoch. Before, it was the earlier fork's version. - After this change, `ChainSpec::next_fork_epoch` is used only by its own test. I kept it, because it is public API. I can remove it if you prefer. - Prysm, Lodestar, and Nimbus already use this rule. The same change is open for Teku, Caplin, and Grandine. * Remove redundant todo (#10195) ## Issue Addressed N/A ## Proposed Changes I think we just forgot to remove this conversion. The envelope errors are handled correctly downstream already * Trust the system CA store for outbound HTTPS (#10110) ## Issue Addressed #10105 System trust was lost in #4650, restored in #4793 and lost again in #8768 when OpenSSL was removed. ## Proposed Changes - Enable reqwest's `rustls-tls-native-roots` feature alongside `rustls-tls`, so the shared client loads system roots as well as the bundled webpki roots. - Update documentation in the Web3Signer guide > [!NOTE] No new crate enters the tree: `rustls-native-certs` was already a transitive dependency, so the lockfile only gains two edges. ## Additional Info One thing that caught us out: if either `SSL_CERT_FILE` or `SSL_CERT_DIR` is set, `rustls-native-certs` loads only from there and skips the platform store. Our base image already sets `SSL_CERT_FILE`, so we had to set `SSL_CERT_DIR` too before the CA we'd mounted into a directory was picked up. `reqwest` adds the bundled webpki roots separately, so public HTTPS keeps working either way. Whilst a global change, I modified `book/src/advanced_web3signer.md` since thats where `root_certificate_path` is documented. I'm fine with moving it somewhere more general if that's preferred. ### Testing Tested this against a local rustls server using a private CA. It connects when the CA is in `SSL_CERT_FILE`, connects when it's in `SSL_CERT_DIR`, and still rejects the connection when the CA isn't present. With the feature turned off again it rejects even with `SSL_CERT_FILE` set, which is what we hit on v8.2.2. Public HTTPS kept working throughout. `cargo check --workspace --all-targets` and `make mdlint` both pass. * Fix nightly tests failing on phase0 and altair (#10200) ## Issue Addressed The nightly tests have been failing on phase0 and altair since #10160 (e.g. https://github.com/sigp/lighthouse/actions/runs/36985385774). Six of the new `fast_confirmation_restart` tests fail because FCR never confirms a block ahead of finality, e.g.: ``` FCR should have confirmed a block ahead of the finalized checkpoint ``` Before Bellatrix there's no execution block hash, so `run_fcr` returns `NodeHasNoBlockHash` and the node always falls back to the finalized block: https://github.com/sigp/lighthouse/blob/d917caf682a24e076f8d4311f435c369043038d7/beacon_node/beacon_chain/src/canonical_head.rs#L1400-L1404 We only run recent forks on PR CI, so this wasn't caught there. ## Proposed Changes Skip all tests in `fast_confirmation_restart.rs` before Bellatrix, same as we do in `payload_invalidation.rs`. The other tests in the file only pass pre-Bellatrix because both nodes stay at the finalized block, so they don't test anything there. * Subscribe to next fork topics an epoch early (#10204) ## Description Subscribes to all topics of the next fork digest one epoch early. Alternative to #9794 where we are just subscribing to `proposer_preferences` 1 epoch early but all other topics are left unchanged. - Publish proposer preferences on the digest of their proposal epoch. - Keep the next digest when we unsubscribe from old topics. - Fix startup and sync catch-up for the next digest. - Add a test that steps through fork schedules slot by slot. Closes #9041 * Propagate beacon chain database read errors (#10217) ## Issue Addressed https://github.com/sigp/lighthouse/issues/10216 ## Proposed Changes Propagate errors from `store_contains_beacon_chain()` during beacon chain startup instead of treating database read failures as an absent chain. This preserves the database error for `FromStore` startup rather than selecting the DepositContract genesis path. ## Additional Info * Remove deprecated builder `submitBlindedBlock` v1 (#10213) Deprecated here https://github.com/ethereum/builder-specs/pull/123 * Use payload envelope summary in head snapshot and block production (#10187) The head snapshot and the proposer re-org path only need fields from the payload envelope summary. Load the summary instead of the full envelope, so these paths no longer read the payload body or fail when it is pruned. * Add documentation for fast confirmation rule (#10183) Add some docs to the FCR * Add compile-time Spec alias and migrate types tests (#10158) ## Issue Addressed The next step in splitting up #9229, following #10051. ## Proposed Changes - Add a compile-time `Spec` preset. It is set to `MainnetEthSpec` by default. Other presets are selected with `spec-minimal`/`spec-gnosis`. - Switch the `types` tests to use `Spec` directly. The rest of the tests will follow in future PRs. - Add a `spec-minimal` feature to the crates which will need it later. - Add `make test-spec-minimal` and `make lint-spec-minimal`, along with CI jobs for each. ## Additional Info Only tests use `Spec`. The binaries still pick their preset when they start, so nothing changes at for production code at runtime, it continues to use EthSpec. * Revert the execution proof availability gate (#10233) ## Issue Addressed - Current approach for optional proofs is #10198 ## Proposed Changes - Revert #9808 * Fix Web3Signer Gloas request types for remote-signing-api v1.4.0 (#10207) ## Description Web3Signer 26.9.0 follows remote-signing-api v1.4.0 for Gloas signing. Lighthouse still sent the old request shapes (`PAYLOAD_ATTESTATION` / `REQUEST_AUTH`, unwrapped payloads), so Web3Signer would reject them. Rename the message types, wrap Gloas objects as `{version, data}`, and omit `fork_info` for `BUILDER_REQUEST_AUTH`. Add Sepolia Gloas coverage in `web3signer_tests`, pin Web3Signer 26.9.0 from GitHub, and require Java 25 for those tests. Fixes #9252 ## Test plan - [x] `cargo nextest run -p signing_method --release` - [x] `cargo nextest run -p web3signer_tests sepolia_gloas_types --release` * Split up EF tests to run each preset separately (#10237) ## Issue Addressed Follows on from #10158, another piece of #9229 ## Proposed Changes Move the EF tests to run separately using compile time preset selection. * Bump PTC SSE queue (#10239) ## Issue Addressed Closes: - https://github.com/sigp/lighthouse/issues/10214 ## Proposed Changes Bump the queue cap to 512 so we can take a whole slot worth of PTC messages in a burst. This does not meaningfully increase memory usage. * Fix PTC duties at the Gloas fork boundary (#10193) Closes #9584 At the Gloas fork, the PTC duties endpoint returned 500 `IncorrectStateVariant` while the head state was still Fulu, so the VC missed PTC duties for slot 0 of the fork epoch. The BN now serves fork-epoch duties from the advanced head state at slot 0 and returns 400 before the fork. https://discordapp.com/channels/595666850260713488/1555299785437610066 * Fix blob ordering when filtering blobs by versioned hash (#9944) ## Issue Addressed Closes #9941. ## Proposed Changes - `GET /eth/v1/beacon/blobs/{block_id}` now returns blobs in the order of the KZG commitments in the block, regardless of the order of the requested `versioned_hashes` ([spec](https://github.com/ethereum/beacon-APIs/blob/master/apis/beacon/blobs/blobs.yaml#L8-L9)). This is done by sorting the derived blob indices before fetching the blobs - Add a test that requests the versioned hashes in reverse order and asserts that the returned blobs follow the commitment order ## Additional Info - The second point of the issue (response `data` being a list of `{"blob": …}` objects instead of hex strings) does not apply: `BlobWrapper` is `#[serde(transparent)]`, so the `data` field in the response is already a flat array of hex strings. I validated this locally with a throwaway request test against the `http_api` test server (not included in this PR) * Align the EIP-8025 proof types and gossip rules with the spec (#10236) ## Issue Addressed This PR represents the final state of EIP-8025 spec https://github.com/ethereum/consensus-specs/pull/5639 ## Proposed Changes Update types, verifier API and gossip rules * Add inclusion_list_bits to ExecutionPayloadBid (#9729) This PR is a follow-up on [the base FOCIL types & constants PR](https://github.com/sigp/lighthouse/pull/9708). ## Proposed Changes - Add `inclusion_list_bits` to the Heze `ExecutionPayloadBid` - Convert `ExecutionPayloadBid` and `SignedExecutionPayloadBid` to `superstruct(Gloas, Heze)`. Most of the changes in the PR are cascading from this decision, because fields are migrated to getters as part of this change. - Later edit: post [#9714](https://github.com/sigp/lighthouse/pull/9714) merge, local block production also builds Heze bids ## Additional Info - `inclusion_list_bits` defaults to empty everywhere, so we're not computing or reading it yet. The main goal is to land this early so that we freeze the Heze bid and state layout before downstream FOCIL work builds on it. - The Gloas variant is byte-identical to the old struct's version, so the `ssz_static` vectors for the bid and `BeaconState` pass unchanged. - This PR was tested locally by running the following commands: - `make cargo-fmt` - `make lint` - `make test` - `make test-ef` Co-authored-by: Eitan Seri- Levi <eserilev@gmail.com> * Add `safe_block_hash` and `finalized_block_hash` to Payload Attributes event (#10244) ## Issue Addressed Addressed the following item in the checklist #9045 - Modify `payload_attributes` event to add `safe_block_hash` and `finalized_block_hash` ## Proposed Changes - Add `safe_block_hash` and `finalized_block_hash` parameters to `SseExtendedPayloadAttributesGeneric` - If Gloas is not enabled, `safe_block_hash` and `finalized_block_hash` is set to None else they are to `justified_hash` and `finalized_hash` from `forkchoice_update_params` respectively * update libp2p (#10229) simplification of https://github.com/sigp/lighthouse/pull/10115/ * Implement optional proofs with fork-choice optimistic (#10198) ## Issue Addressed Implement the second part of optional proofs. With this code the consumer of proofs is complete assuming recursive proofs. Proofs are produced and seeded into gossip by another client, out of scope of this PR. - part of https://github.com/sigp/lighthouse/issues/9658 ## Proposed Changes Now that gloas optimistic sync is merged, optional proofs are very easy to support: - Use existing payload and data availability cache for those two things. - Once they arrive immediately import with Optimistic status - Wait for proofs to arrive => once you get enough proofs flip the fork-choice status of that node to VALID * Make the execution layer optional with proof engine (#10262) ## Issue Addressed Allow Lighthouse to run without EL if there's a local proof engine and the head is post gloas. We allow nodes to switch between having and not having an EL as long as the latest verified head is Gloas. - Part of https://github.com/sigp/lighthouse/issues/9658 ## Proposed Changes Stop sending new payload, and FCUs. Do no attempt local block production. Automatically disable get_blobs optimization. ## Additional Info Please provide any additional information. For example, future considerations or information useful for reviewers. * Add POST /eth/v1/beacon/execution_proofs (#10210) ## Description Adds `POST /eth/v1/beacon/execution_proofs`: an SSZ list of `SignedExecutionProofEnvelope`, each gossip-verified, published and cached. EIP-8025 proofs enter the network by submission. A prover signs and submits on its own schedule, since a block's first proof lands minutes after the block. Spec: ethereum/beacon-APIs#660. - part of https://github.com/sigp/lighthouse/issues/9658 ## Notes Flagged as work in progress until spec is merged ethereum/beacon-APIs#660 * Split `beacon_chain` tests by preset (#10246) ## Issue Addressed The next step in splitting up #9229, following #10237. ## Proposed Changes - Switch the `beacon_chain` tests to `Spec`. - Split the `beacon_chain` tests between those run in the `minimal` preset and those run under the `mainnet` preset. * Fix empty BlocksByRoot responses during Gloas column publish (#9976) ## Description - Gloas skipped DA pre-import cache insert, so columns could publish while `BeaconBlocksByRoot` returned empty and peers downscored/disconnected - Cache the Gloas block in `pending_payload_cache` (not the DA checker) and serve it via `get_block_process_status` - On gossip, insert before spawning getBlobs/column publish; in `process_block`, insert after consensus verification - Gloas import still does not wait on custody columns Closes #9975 ## Test plan - [x] `cargo nextest run -p beacon_chain --release --test beacon_chain_tests gloas_pre_import_rpc_cache` * Gloas progressive merkle proofs (#9790) ## Issue Addressed Implement EIP-7688 progressive container Merkle proofs AI disclosure: Written by claude fable 5 Co-authored-by: dapplion <guillem.lion.benosa@gmail.com> * Split `http_api` tests by preset (#10284) ## Issue Addressed The next step in splitting up #9229, following #10246. ## Proposed Changes - Switch the `http_api` tests to `Spec`, so they run with their compile-time preset. - Split the `http_api` integration tests into two, one for each preset. * Fix cross builds after cc bump (#10278) ## Issue Addressed #10229 set `CXX = "clang++"` in `.cargo/config.toml` to work around LevelDB's `-Wthread-safety` probe. The `cross` images only ship GCC, so all cross builds (docker, release, binary-builder) on `unstable` now fail in `leveldb-sys`: - x86_64: `failed to find tool "clang++"` - aarch64: the image's `CXX_aarch64_unknown_linux_gnu` takes precedence, so GCC is used and hits the original `-Wthread-safety` error ## Proposed Changes - In `Cross.toml`, use `g++` inside cross containers. - Apply the LevelDB workaround through a small CMake wrapper (`scripts/cross/cmake-wrapper.sh`) that pre-seeds `HAVE_CLANG_THREAD_SAFETY=OFF`. ## Additional Info Tested on a fork: `lighthouse` and `lcli` `maxperf` builds pass for x86_64 and aarch64. 🤖 Generated with [Claude Code](https://claude.com/claude-code) * Unify `BlobInfo` and `DataColumnInfo` into `DataInfo` (#9957) ## Issue Addressed Pruning can behave weirdly on freshly synced nodes, as the `oldest_blob_slot` is not correctly updated. ## Proposed Changes To avoid this and possibly other related issues, we unify the two separate markers into one: `DataInfo`. Details: - `DataInfo` is now initialized in a way similar to the split: `open` does not set any presumptive value if `DataInfo` is not set, but relies on the initialisation method (migration, checkpoint sync, genesis sync) to set an appropriate value - `oldest_data_slot` is not an `Option` - nowadays nodes only operate with Fulu in the past (we explicitly dropped support for running during earlier forks when we ripped out Blob gossiping etc). So this always has a sensible value, except during initialization - similar to the split. ## Additional Info K-46 * Resolve the fork from the block slot when loading the http-sync cache (#10276) ## Issue Addressed Closes https://github.com/sigp/lighthouse/issues/10275…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The default
datais the UTF-8 bytes of the builder URL exactly as advertised, so a trailing/, an explicit:443or different casing on the proposer side fails the builder's check.Use the builder's hostname instead: lowercased, without scheme, userinfo, port or path. It is a pure function of the configured URL, so all validator clients derive the same bytes, and it is only applied when constructing the
BuilderRequestAuth, the signed bytes are still verified unchanged.Builders that need a finer identity than their hostname can still agree
dataout of band. Theauth_datadescriptions in keymanager-APIs and beacon-APIs are updated in ethereum/keymanager-APIs#94 and ethereum/beacon-APIs#642.