Skip to content

fix(engine): use correct V4P11 response envelope and Prague3 payload handling#239

Open
calbera wants to merge 6 commits intomainfrom
claude/analyze-prague3-bug-zmIlK
Open

fix(engine): use correct V4P11 response envelope and Prague3 payload handling#239
calbera wants to merge 6 commits intomainfrom
claude/analyze-prague3-bug-zmIlK

Conversation

@calbera
Copy link
Copy Markdown
Contributor

@calbera calbera commented Apr 16, 2026

Wire getPayloadV4P11 response through BerachainExecutionPayloadEnvelopeV4
so parentProposerPubKey is included in the envelope. The EngineTypes
type alias was pointing at the upstream ExecutionPayloadEnvelopeV4 which
lacks the field.

Replace the Prague3 builder hard-stop with an empty block path so the
builder gracefully produces a valid block instead of erroring. Add an
upfront Prague3 rejection in forkchoiceUpdatedV3P11 so FCU never returns
a payloadId the builder cannot serve.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for Berachain-specific execution payload envelope (V4).
    • Introduced Prague3 fork validation checks in fork choice update operations.
  • Refactor

    • Updated payload building logic to handle Prague3 protocol activation.
    • Enhanced payload envelope conversion and handling mechanisms.

Wire getPayloadV4P11 response through BerachainExecutionPayloadEnvelopeV4
so parentProposerPubKey is included in the envelope. The EngineTypes
type alias was pointing at the upstream ExecutionPayloadEnvelopeV4 which
lacks the field.

Replace the Prague3 builder hard-stop with an empty block path so the
builder gracefully produces a valid block instead of erroring. Add an
upfront Prague3 rejection in forkchoiceUpdatedV3P11 so FCU never returns
a payloadId the builder cannot serve.

https://claude.ai/code/session_011iX4hTaTWntopZYE2ZpfMe
Copilot AI review requested due to automatic review settings April 16, 2026 07:45
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 16, 2026

Warning

Rate limit exceeded

@calbera has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 28 minutes and 53 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 28 minutes and 53 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5555f7a1-023d-45f9-961e-922ea8fee3f9

📥 Commits

Reviewing files that changed from the base of the PR and between 471de64 and d90c28d.

📒 Files selected for processing (4)
  • src/engine/payload.rs
  • tests/e2e/mod.rs
  • tests/e2e/prague3_empty_block_test.rs
  • tests/fixtures/eth-genesis-prague3.json
📝 Walkthrough

Walkthrough

The changes add Prague3 fork-era validation and payload-handling logic across the engine layer. The payload builder now skips transaction processing when Prague3 is active, the V4 execution envelope type is updated to use a Berachain-specific version, and RPC fork-choice validation rejects Prague3 timestamps.

Changes

Cohort / File(s) Summary
Prague3 Fork Validation
src/engine/builder.rs, src/engine/rpc.rs
Modified payload building to skip transaction-processing logic when Prague3 is active; added timestamp-based Prague3 validation to fork_choice_updated_v3_p11 to reject unsupported fork activation.
V4 Envelope Type Update
src/engine/mod.rs, src/engine/payload.rs
Changed ExecutionPayloadEnvelopeV4 from upstream type to Berachain-specific BerachainExecutionPayloadEnvelopeV4; updated try_into_v4 to construct the envelope with execution_requests and parent_proposer_pub_key fields.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • rezzmah
  • fridrik01

Poem

🐰 Prague3 arrives, the fork takes shape,
Payloads skip their dance and drape,
V4 envelopes, custom and new,
With parent keys and requests true!
A rabbit hops through validation's gate,
Building blocks at protocol's fate! 🌙

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main changes: fixing the V4P11 response envelope type and Prague3 payload handling behavior in the engine module.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/analyze-prague3-bug-zmIlK

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@calbera calbera changed the title claude/analyze-prague3-bug-zmIlK fix(engine): V4P11 response envelope and Prague3 payload handling Apr 16, 2026
@calbera calbera requested a review from a team April 16, 2026 07:46
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 471de6497f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/engine/rpc.rs Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates Berachain’s Engine API v4 envelope typing so getPayloadV4P11 responses include the Berachain-specific parentProposerPubKey, and adjusts Prague3 behavior to avoid builder hard failures by producing empty blocks while preventing FCU from returning unservable payload IDs during Prague3.

Changes:

  • Route EngineTypes’ v4 envelope type to BerachainExecutionPayloadEnvelopeV4 so the extra Berachain field is serialized in v4 payload envelopes.
  • Extend v4 payload conversion to populate parent_proposer_pub_key from the built block header.
  • Replace the Prague3 builder hard-stop with an “empty block” path and add a Prague3 rejection in forkchoiceUpdatedV3P11.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/engine/rpc.rs Reject forkchoiceUpdatedV3P11 when Berachain Prague3 is active to avoid returning incompatible payload IDs.
src/engine/payload.rs Convert built payloads into Berachain’s v4 envelope type and populate parent_proposer_pub_key.
src/engine/mod.rs Switch EngineTypes::ExecutionPayloadEnvelopeV4 to BerachainExecutionPayloadEnvelopeV4.
src/engine/builder.rs Build empty blocks during Prague3 instead of erroring; refactor transaction inclusion under a !prague3_active guard.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/engine/builder.rs
Comment thread src/engine/payload.rs
Comment thread src/engine/builder.rs
Comment thread src/engine/payload.rs
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/engine/mod.rs (1)

111-123: ⚠️ Potential issue | 🟠 Major

Preserve the standard engine_getPayloadV4 wire shape.

EngineTypes::ExecutionPayloadEnvelopeV4 is used by both engine_getPayloadV4 and engine_getPayloadV4P11, so this remap makes the standard V4 method serialize BerachainExecutionPayloadEnvelopeV4 too. As written, pre-Prague1 responses will include parentProposerPubKey: null, which adds a non-spec field to engine_getPayloadV4. Make the Berachain extension field conditional so only P11/Prague1 responses carry it.

Suggested fix
 pub struct BerachainExecutionPayloadEnvelopeV4 {
     /// Inner [`ExecutionPayloadEnvelopeV3`].
     #[deref]
     #[deref_mut]
     #[serde(flatten)]
     pub envelope_inner: ExecutionPayloadEnvelopeV3,
@@
     /// A list of opaque [EIP-7685][eip7685] requests.
     ///
     /// [eip7685]: https://eips.ethereum.org/EIPS/eip-7685
     pub execution_requests: Requests,
     /// Introduced in BRIP-0004
+    #[serde(default, skip_serializing_if = "Option::is_none")]
     pub parent_proposer_pub_key: Option<BlsPublicKey>,
 }

Also applies to: 126-130

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/engine/mod.rs` around lines 111 - 123, The Berachain-specific field
parent_proposer_pub_key on BerachainExecutionPayloadEnvelopeV4 is being
serialized as null for standard engine_getPayloadV4 responses; update the struct
so the field is omitted when empty by adding serde's conditional attr (e.g.,
#[serde(skip_serializing_if = "Option::is_none")]) to parent_proposer_pub_key on
BerachainExecutionPayloadEnvelopeV4 (and the other similar occurrence around
lines 126-130), so EngineTypes::ExecutionPayloadEnvelopeV4 used by
engine_getPayloadV4 does not include the non-spec field unless present for
engine_getPayloadV4P11/Prague1.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/engine/mod.rs`:
- Around line 111-123: The Berachain-specific field parent_proposer_pub_key on
BerachainExecutionPayloadEnvelopeV4 is being serialized as null for standard
engine_getPayloadV4 responses; update the struct so the field is omitted when
empty by adding serde's conditional attr (e.g., #[serde(skip_serializing_if =
"Option::is_none")]) to parent_proposer_pub_key on
BerachainExecutionPayloadEnvelopeV4 (and the other similar occurrence around
lines 126-130), so EngineTypes::ExecutionPayloadEnvelopeV4 used by
engine_getPayloadV4 does not include the non-spec field unless present for
engine_getPayloadV4P11/Prague1.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ba3223ad-ec7d-4cd2-a9f9-2bcca4d8fa53

📥 Commits

Reviewing files that changed from the base of the PR and between 26762fb and 471de64.

📒 Files selected for processing (4)
  • src/engine/builder.rs
  • src/engine/mod.rs
  • src/engine/payload.rs
  • src/engine/rpc.rs

@calbera calbera marked this pull request as draft April 16, 2026 08:37
claude added 2 commits April 16, 2026 08:56
Exercise the builder path where Prague3 is active and transaction
selection is skipped. The test launches a node with a Prague3-at-genesis
chainspec, advances one block, and asserts the resulting block contains
zero transactions.

https://claude.ai/code/session_011iX4hTaTWntopZYE2ZpfMe
Construct a BerachainBuiltPayload with a known prev_proposer_pubkey in
the block header, convert via try_into_v4, and verify the resulting
envelope carries the correct parent_proposer_pub_key and
execution_requests. A second case covers the None-pubkey / no-requests
default path.

https://claude.ai/code/session_011iX4hTaTWntopZYE2ZpfMe
@calbera calbera changed the title fix(engine): V4P11 response envelope and Prague3 payload handling fix(engine): use correct V4P11 response envelope and Prague3 payload handling Apr 16, 2026
claude added 2 commits April 16, 2026 09:35
Prague1+ blocks always contain the PoL system transaction injected by
apply_pre_execution_changes. The Prague3 builder skip only bypasses
pool transaction selection, so the correct assertion is exactly one
transaction (the PoL tx), not zero.

https://claude.ai/code/session_011iX4hTaTWntopZYE2ZpfMe
V3P11 is the only FCU path available after Prague1 activation. Rejecting
Prague3 timestamps here would prevent the CL from obtaining a payloadId
during that window, making the empty-block builder path unreachable.
The builder already handles Prague3 gracefully by skipping pool
transactions, so FCU should accept the request.

https://claude.ai/code/session_011iX4hTaTWntopZYE2ZpfMe
@calbera calbera marked this pull request as ready for review April 16, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants