Build and submit a Gloas/Amsterdam block - #575
Open
0w3n-d wants to merge 1 commit into
Open
Conversation
Set the header's slot number from the proposal slot and carry the block access list ethrex records, then submit it in the Gloas shape. Size the payout reserve for EIP-8037's account-creation state gas, without which a fee recipient's first payment runs out of gas. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 4, 2026
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.
Issue: #561 (step 4 of 6)
What this PR does
The building role now produces Amsterdam blocks and submits them in the Gloas
shape. Two fork decisions drive it, and they are independent:
is_amsterdam_activated(slot.timestamp)sets the header's EIP-7843 slot number and keeps the EIP-7928 list ethrex
already records but which
BuiltBlockwas discarding.chain_info.fork_at_slot(slot)selects
SignedBidSubmissionGloas. The relay decodes by the fork its clockreports, so the builder reads the same spec or its bytes are undecodable.
When the two disagree the submission is refused rather than sent. An Amsterdam
block in a Fulu shape silently drops the list; the simulator then rebuilds a
header whose hash is not the one signed, and every bid dies as a hash mismatch
with nothing to point at.
The finding that made this more than plumbing
Under Amsterdam the trailing payout needs 204600 gas, not 21000, whenever the
proposer's fee recipient does not yet exist on chain. EIP-8037 charges state
gas for the account the payment creates: 120 state bytes at 1530 each = 183600,
on top of the transfer's 21000.
With the old fixed reserve every such block was lost —
PayoutReverted, from anout-of-gas that consumed the whole limit. On a fresh testnet fee recipients
generally don't exist yet, so this would have broken the builder on the exact
network step 4 exists to enable, and the error message pointed at the payout
rather than at gas.
The reserve is now sized from state:
payout_gas_reservecovers the transfer,and the creation charge is added only when the recipient is absent. It is read
twice — before the fill to size the reserve, and after it for the transaction —
so a recipient created earlier in the same block is not charged for twice. The
constants come from
ethrex-levmrather than being hardcoded, so they cannotdrift from the rules the simulator enforces when the ethrex pin moves.
A related property worth knowing, which this PR does not change: under Amsterdam
an ordinary 21000-gas transfer to a fresh address also fails. That is EIP-8037
applying to all traffic, not something the builder can fix; such transactions
are included with failed receipts, which is correct.
What this PR deliberately does not do
path is untouched.
than the reserve still fails and the slot is skipped, as before. rbuilder
searches for this; it stays a stage-2 item.
be: the in-block read already reports the account as existing from the next
block on.
Tests
Tests were written first, as in every earlier step. 15 new tests; 414 pass in
total (399 before).
The end-to-end pair is the one that matters: build a block, sign it the way the
relay will receive it, and validate it with our own step 3 simulation role,
asserting 200. I checked it is not vacuous by flipping one byte of the list —
the test then fails with the expected block hash mismatch. Both forks are
covered.
Also covered: an Amsterdam block carries both header fields and the exact bytes
the header hashed; a pre-Amsterdam block carries neither, guarding against
changing every Fulu block hash; the slot number is the proposal slot, not the
block number; the in-block payout is unchanged; mempool transactions still fit
alongside the larger reserve; the three payout-gas cases as a unit; a first
payment to an absent recipient really succeeds; a recipient created earlier in
the block needs no extra reserve; the Gloas submission decodes through the
relay's own decoder; the Fulu shape is unchanged; both fork-mismatch directions
are refused by name; and the bid trace's slot matches the header's, which is the
contract step 3 relies on.
Reviewer checklist
lint,unit-test) is green