feat: implement proposer preferences for Gloas (EIP-7732)#1
Open
lodekeeper wants to merge 2 commits intounstablefrom
Open
feat: implement proposer preferences for Gloas (EIP-7732)#1lodekeeper wants to merge 2 commits intounstablefrom
lodekeeper wants to merge 2 commits intounstablefrom
Conversation
End-to-end proposer preferences implementation: **Beacon Node:** - New gossip topic `proposer_preferences` with validation, scoring, queue config - ProposerPreferencesPool + SeenProposerPreferences (with pruning) - Validation: epoch+1 check, proposer lookahead match, dedup, BLS signature - Bid validation: require matching preferences (fee_recipient + gas_limit) - API: POST /eth/v1/validator/proposer_preferences (submit) - API: GET /eth/v1/beacon/pool/proposer_preferences (query) - SSE event: proposer_preferences - Metrics: pool size, gossip/api insert outcomes **Validator Client:** - pollProposerPreferences: epoch-boundary polling, queries next-epoch proposer duties, signs preferences with fee_recipient/gas_limit, submits to BN - ValidatorStore.signProposerPreferences with DOMAIN_PROPOSER_PREFERENCES - External signer support (PROPOSER_PREFERENCES message type) **State Transition:** - getProposerPreferencesSigningRoot helper Addresses beacon-APIs ChainSafe#570 and ChainSafe#435. Resolves TODO GLOAS comments in bid validation. Generated with assistance from AI (Codex CLI + Claude).
- Use proposalSlot (not stateSlot) for domain computation to ensure correct fork version at the Gloas fork boundary - Include PROPOSER_PREFERENCES_WEIGHT in maxPositiveScore sum
nflaig
added a commit
that referenced
this pull request
Feb 16, 2026
…sponse (ChainSafe#8908) ## Motivation The e2e reqresp tests "should handle a server error" and "should handle a server error after emitting two blocks" have been consistently flaky, appearing in **~90% of all CI E2E test failures**. Analysis of ~100 recent CI runs confirmed this as the #1 source of E2E flakiness. The failure pattern: ``` expected { code: "REQUEST_ERROR_SERVER_ERROR", errorMessage: "" } to deeply equal { code: "REQUEST_ERROR_SERVER_ERROR", errorMessage: "TEST_EXAMPLE_ERROR_1234" } ``` The error status code is received correctly, but the error message is empty. ## Root Cause `responseEncodeError()` yields the error status byte and snappy-encoded error message as **separate chunks** through the async generator: ```ts yield Buffer.from([status]); // chunk 1 yield* encodeErrorMessage(errorMessage, protocol.encoding); // chunk 2+ ``` When piped through `stream.sink`, libp2p can close/flush the stream after the first yield completes but before the subsequent error message chunks are delivered to the reader side. The `readErrorMessage()` function on the receiving end then finds no data after the status byte and returns an empty string. ## Fix Collect the status byte and encoded error message into a single `Buffer.concat()` yield, ensuring they are delivered atomically through the stream. This eliminates the race condition without changing the wire format. ## Notes - All existing reqresp unit tests pass (85/85) - The wire format is unchanged — the same bytes are sent, just in a single chunk instead of multiple - This is consistent with how other protocols handle similar issues (combining header + payload) > This PR was authored by an AI contributor. All code was reviewed by sub-agents before submission. --------- Co-authored-by: lodekeeper <lodekeeper@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <175061342+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Nico Flaig <nflaig@protonmail.com>
lodekeeper
added a commit
that referenced
this pull request
Feb 25, 2026
- Remove all write commands (pnpm build/lint, git checkout/merge, gh pr/api) from default allowlist — keep only read-only commands per review feedback - Remove find from allowlist (supports -delete and -exec) - Remove marketplace plugin config (PR #1 closed in favor of this PR) - Use isolated --dataDir /tmp/lodestar-debug in local-mainnet-debug skill instead of touching default mainnet database - Update cleanup section to only remove isolated debug directory
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.
Description
End-to-end proposer preferences implementation for Gloas (EIP-7732), addressing beacon-APIs #570 and #435.
Beacon Node
proposer_preferencestopic with full wiring (GossipType, SSZ type mapping, topic encoding, scoring parameters, FIFO queue, handler)DOMAIN_PROPOSER_PREFERENCESProposerPreferencesPool(slot → preferences) with 2-epoch retention +SeenProposerPreferencestrackingPOST /eth/v1/validator/proposer_preferences— VC submits signed preferencesGET /eth/v1/beacon/pool/proposer_preferences— query pool (optional?slot=filter)proposer_preferencesevent typeValidator Client
pollProposerPreferences: Epoch-boundary polling — queries next-epoch proposer duties, filters own validators, signs preferences (fee_recipient + gas_limit from config), submits to BNValidatorStore.signProposerPreferences: Signs withDOMAIN_PROPOSER_PREFERENCESPROPOSER_PREFERENCESmessage type in web3signer clientState Transition
getProposerPreferencesSigningRoot: Computes signing root for proposer preferencesTests
ProposerPreferencesPool(insert, dedup, prune)Companion
Generated with assistance from AI (Codex CLI + Claude)