feat(actions): Wire Production Payload Builder#1861
Conversation
🟡 Heimdall Review Status
|
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
cb494fe to
4b29e90
Compare
2408906 to
a4b6082
Compare
d689e5d to
a26a7f2
Compare
| let block_hash = block.hash(); | ||
| let parent_beacon_block_root = block.header().parent_beacon_block_root(); | ||
| let (payload, _sidecar) = | ||
| OpExecutionPayload::from_block_unchecked(block_hash, &block.clone_block()); |
There was a problem hiding this comment.
The sidecar returned by from_block_unchecked is discarded here, but the caller (L2Sequencer::try_build_next_block_with_transactions) then manually reconstructs a sidecar from the envelope to restore PBBR and requests_hash (l2.rs:546-560). This round-trip is fragile: if from_block_unchecked ever changes what it puts in the sidecar vs the payload, the reconstruction logic in L2Sequencer could silently diverge.
Consider returning the sidecar as part of OpExecutionPayloadEnvelope (or a richer return type), or at minimum passing the built payload's sidecar through so the caller doesn't have to reconstruct it from scratch.
|
|
||
| // 5. Insert the block into the engine (updates canonical head). | ||
| self.engine_client | ||
| .insert_unsafe_payload(envelope.clone()) |
There was a problem hiding this comment.
envelope.clone() deep-clones the entire OpExecutionPayloadEnvelope (including all transactions) only to immediately pass the original to try_into_block_with_sidecar on line 561. Since insert_unsafe_payload takes ownership, consider reordering: extract the fields needed for the BaseBlock conversion first, then pass the original envelope to insert_unsafe_payload.
Alternatively, since insert_unsafe_payload on the in-process engine client is a no-op (the skip-check fires because the block was just built by start_build_block), the clone is paying for work that doesn't do anything.
Review SummaryThis PR replaces the bespoke Key observationsCorrectness: The core block-building and state-commitment flow in New findings (this review):
Previously raised findings still applicable (from prior review run — not re-posted as inline comments):
VerdictThe PR achieves its stated goal of wiring the production payload builder into the action test harness. The architecture is an improvement. The findings above are mostly hardening suggestions and style issues — none are blocking for the current test-only scope. |
Summary
Replaces the bespoke
StatefulL2ExecutorinsideActionEngineClientwith the realOpPayloadBuilderstack.L2Sequencernow uses the productionL1OriginSelectorandStatefulAttributesBuilderto produce payload attributes, then delegates block building toActionEngineClientviastart_build_block/get_sealed_payload/insert_unsafe_payload. This eliminates the divergence between the test harness and the production block-building code path, so action tests exercise the real execution pipeline end-to-end.get_next_payload_l1_originandbuild_attributesonPayloadBuilderare madepubto support this wiring.