Merge the ethrex builder stack into the Gloas stack - #562
Open
0w3n-d wants to merge 30 commits into
Open
Conversation
Co-authored-by: vladimir-ea <vladimir@gattaca.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
… simulator (#506) Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…ble failures (#508) Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
--merging.config activates merging, the new --sim.config activates simulation, neither is a startup error. The relay signer loads only for merging. The simulation role boots the node only; its servers come later. Step 1 of #527. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…mmon The disallow list's parsing and digest, and the Safe multiSend payment recognition, carry no reth types. Move them so the ethrex simulator uses the same code. The functions and their tests move verbatim. Step 2 of #527. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
BlockValidator turns an ExecutionPayloadV3 into the block it describes, checks the bid trace against that block, and finds the parent within the validation window. Nothing executes yet. The head comes from the node's watch channel rather than a store read per call, which keeps prepare synchronous. Step 3 of #527. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Runs validate_block_pre_execution, executes on the parent state, then checks gas used, receipts root, requests hash and state root. The store is only read: the submitted block is never persisted. Step 4 of #527. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The recipient's whole-block balance delta decides first. When the proposer also spends, the payment must be recognisable: a direct transfer, or a PAYMENT_FORWARDER call where its runtime is deployed. Merged blocks sum the base payment tx and the trailing distribution tx. helix-common becomes a runtime dependency for the payment constants. Ports the current reth behavior unchanged, including the multiSend gap that #533 will close for both simulators at once. Step 5 of #527. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Interaction means effect: a state change, or a transaction addressed to the account. The coinbase and the proposer fee recipient are checked directly, since neither has to change state. Reading an account is not interaction. The reth simulator rejects such a block, so the two disagree; see the test that records it. Step 6 of #527. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The submission carries one bundle for the whole block, so the block's blob versioned hashes must match its commitments in order. ethrex's BlobsBundle::validate is per transaction and does not fit that shape, so this checks the lengths and hashes and calls verify_cell_kzg_proof_batch directly. Blob gas accounting needs nothing: verify_blob_gas_usage already runs in validate_block_pre_execution. Step 8 of #527. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
/validate and /validate_merged decode the relay's SSZ requests, run the validator on a blocking thread under a semaphore, and answer 200 or 400 with the reason. A dehydrated submission answers 424 so the relay retries with full bytes. The disallow list refreshes from the configured endpoint. main now builds the validator and spawns both, so the module no longer needs allow(dead_code). Drops rpc_addr: no JSON-RPC is served, and an unused config field is a trap. The relay reaches this role through its simulator ssz_url. Step 9 of #527. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
README covers both roles, how to run each, and where the simulation role differs from crates/simulator: no inclusion lists, a narrower disallow rule, SSZ only, and release builds only. Step 10 of #527. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Turn `Roles` into a struct of optional configs. As an enum a third role needs seven variants. The building role takes its own two keys: `RELAY_KEY` is already read as secp256k1 by the merging role and as BLS by `load_keypair`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The beacon node supplies the consensus fields and the relay supplies the proposer. Neither alone is enough to build. Take the fee recipient and gas limit from the duty. The event carries a `suggested_fee_recipient`, but it is the local validator's. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Reserve the payout gas by lowering `remaining_gas` before the fill and restoring it after. `fill_transactions` spends the whole budget. Raise the default subsidy to 0.001 ETH. At 1 gwei the old default could not cover the payout's own gas, so every idle slot was skipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Take the builder domain from the beacon node's own spec and genesis. A hardcoded genesis fork version makes the relay drop every bid, silently. Check the blobs bundle by proof count, not by `version`. ethrex's `AddAssign` does not propagate it, so an aggregate always reads 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sleep to an absolute deadline. The offsets share one origin, so sleeping them end to end would land every attempt after the last. Key the best bid by slot and parent. After a re-org the earlier bid sits on a dead parent, so a lower value must still go out. Drop `self_validate`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both stacks branch from develop and neither can be tested on a Gloas testnet alone. The only conflict is two test functions added at the same point in `hydration.rs`. Both are kept. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
7 tasks
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 0 of 6)
What this PR does
Merges the ethrex builder stack (#560, which carries the simulator stack
#528-#544 beneath it) into the Gloas relay stack (#515). Both branch from
develop, and neither can be exercised on a Gloas testnet alone: the relaystack has no builder or simulator that can produce or validate a Gloas block,
and the builder stack is entirely Fulu-shaped.
Everything after this in #561 stacks on this branch.
The one conflict
crates/types/src/hydration.rs. Both sides appended test functions at the samepoint, and the diff landed mid-function on each side. Both are kept — all
four tests are present and run:
dehydrated_with_merging_data_decodes_under_gloas_fork(Gloas side)dehydrated_bid_submission_decodes_under_gloas_fork(Gloas side)dehydrated_with_adjustments_and_merging_data_ssz_round_trip(builder side)dehydrated_with_adjustments_and_merging_data_split(builder side)No production code conflicted.
What this PR deliberately does not do
No behaviour changes at all. Nothing here makes anything Gloas-ready — the
builder's three roles remain Fulu-shaped, and the two defects #561 records are
untouched:
(
simulator/tile.rs:363), so a Gloas submission reaching an SSZ simulator isvalidated as Fulu;
to_lighthouse_gloas_payloadstill leaves the block access list empty.Those are steps 1 and 2.
Tests
None added; a merge should not need them. The existing suites are the check,
and all pass on the merged tree: helix-types 35, helix-builder 147,
helix-relay 125.
just fmt-checkand the project clippy command are clean, andhelix-builderintroduces no new lints beyond the pre-existing ones recordedin #554.
Reviewer checklist
lint,unit-test) is green