Validate bid gas limit against the payload at bid.parent_block_hash - #864
Merged
hangleang merged 1 commit intoAug 26, 2026
Conversation
validate_execution_payload_bid derived parent_gas_limit from the parent block's post-state latest_execution_payload_bid, i.e. the parent block's own bid, regardless of which payload the bid builds on. The spec keys parent_gas_limit on bid.parent_block_hash: a bid that builds on the parent's parent payload (parent payload withheld) must be checked against that payload's gas limit, which differs from the parent bid's gas limit whenever the gas limit is moving. Such bids were dropped with "bid gas_limit is not compatible with target_gas_limit" on gossip and via the publish REST endpoint (200 + Ignore, never broadcast). Resolve the chain link carrying the payload identified by bid.parent_block_hash (the existing execution_payload_locations index) and use the gas limit committed by that block: its bid post-Gloas, the payload itself pre-Gloas. Adds ExecutionPayload::gas_limit for the latter.
hangleang
approved these changes
Aug 26, 2026
hangleang
merged commit Aug 26, 2026
9d22f7c
into
grandinetech:glamsterdam-devnet-8
1 of 9 checks passed
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.
What
Store::validate_execution_payload_bidderivedparent_gas_limitfromstate_at(bid.parent_block_root).latest_execution_payload_bid().gas_limit— the parent block's own bid — regardless of which payload the bid builds on. The spec keys the check on the payload the bid actually extends:(https://github.com/ethereum/consensus-specs/blob/a670e0193446474bb1775ec94a93ca6fbaa11a89/specs/gloas/p2p-interface.md#L995-L1000)
A bid with
parent_block_root = headandparent_block_hash = head_bid.parent_block_hash(head payload treated as withheld — whichis_bid_compatible_with_headpermits whenshould_build_on_fullis false) must be checked against the grandparent payload's gas limit. Whenever the gas limit is moving, that differs from the head bid's gas limit by one EIP-1559 step, so a spec-correct bid was dropped withbid gas_limit is not compatible with target_gas_limit— on gossip, and viaPOST /eth/v1/beacon/execution_payload_bids, where it results in a 200 with anIgnoreand no broadcast.This PR resolves the chain link carrying the payload identified by
bid.parent_block_hashthrough the existingexecution_payload_locationsindex (replacing the barecontains_keyexistence check) and uses the gas limit committed by that block: its bid post-Gloas, the execution payload itself for a pre-Gloas block at the fork boundary. Envelopes must match their bid'sgas_limit(already enforced at envelope processing), so the bid value is the payload value.ExecutionPayload::gas_limitis added to the trait for the pre-Gloas case.Why
Seen on glamsterdam-devnet-8 (gas limit ramping under EIP-8261). Slot 85165: payload at 85163 had gas limit 199411976, payload at 85164 (head) had 199606713, target 200000000. A builder's parent-empty bid carried 199606713 = 199411976 + 199411976/1024 − 1, correct for the payload it builds on; comparing against the head bid (199606713) makes it look like it failed to step toward the target.
Same class of bug was found in prysm (OffchainLabs/prysm#17405), lighthouse (sigp/lighthouse#9905) and nimbus (status-im/nimbus-eth2#8941); lodestar and teku are correct. The spec gossip test vectors don't cover empty-head bids yet (every case uses the head's own payload as
parent_block_hash); a vector PR is in progress.Testing
cargo check/cargo clippy -p grandine --no-default-features --features default-networks,bls/blst,kzg_utils/blstandcargo fmt --checkon the changed crates. Targetingglamsterdam-devnet-8per the devnet image; happy to retarget or forward-port.