Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix parent_beacon_block_root during proposer prep #4703

Merged

Conversation

michaelsproul
Copy link
Member

Issue Addressed

Fix a bug whereby Lighthouse would send the wrong parent_beacon_block_root in the payload attributes when preparing a payload.

We were sending the root of the parent of the canonical head block in all cases, which is wrong most of the time when we want to build upon the canonical head. In this case, we should send the root of the canonical head block itself (this is specced in EIP-4788). Using the parent root happened to be correct in the case of a single-slot re-org, although this was just a happy accident.

The bug only has low impact because when we actually request a payload we use the correct parent block root, here:

let parent_beacon_block_root = match state {
&BeaconState::Deneb(_) => Some(state.latest_block_header().canonical_root()),

So we get a payload ID cache miss almost every slot, and force the EL to build a payload last-minute off the new (correct) payload attributes.

Proposed changes

  • Fix the issue.
  • Add a test (TODO).

Additional Info

Thanks to @pinges for bringing this to our attention. Besu (correctly) assumed that the headBlockHash should determine the parentBeaconBlockRoot, and was failing to produce blocks with Lighthouse as a result. Besu merged a workaround (which is probably a good defensive measure) in hyperledger/besu#5843.

@michaelsproul michaelsproul added work-in-progress PR is a work-in-progress deneb labels Sep 6, 2023
@michaelsproul michaelsproul changed the title Fix parent_beacon_block_root during prep/reorg Fix parent_beacon_block_root during proposer prep Sep 6, 2023
Copy link
Member

@jimmygchen jimmygchen left a comment

Choose a reason for hiding this comment

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

Nice find, I reviewed the 4788 changes but missed this one!
Looks good to me 👍

@jimmygchen
Copy link
Member

Nice find, I reviewed the 4788 changes but missed this one! Looks good to me 👍

Looks like we have the exact same logic in mock_builder, probably explains why I was getting block hash mismatch! 🎉

let parent_root = head_state.latest_block_header().parent_root;
let payload_attributes = match fork {
ForkName::Merge => {
PayloadAttributes::new(timestamp, *prev_randao, fee_recipient, None, None)
}
// the withdrawals root is filled in by operations
ForkName::Capella => {
PayloadAttributes::new(timestamp, *prev_randao, fee_recipient, Some(vec![]), None)
}
ForkName::Deneb => PayloadAttributes::new(
timestamp,
*prev_randao,
fee_recipient,
Some(vec![]),
Some(parent_root),
),
ForkName::Base | ForkName::Altair => {
return Err(MevError::InvalidFork);
}
};

@michaelsproul
Copy link
Member Author

Ah, that's probably why the builder Deneb test is failing. Although weirdly it succeeds when I run it locally. I'll push that change tomorrow with a test

@realbigsean
Copy link
Member

Ah, awesome! Was struggling to figure this one out yesterday. Thanks Michael!

@jimmygchen
Copy link
Member

Ah, that's probably why the builder Deneb test is failing. Although weirdly it succeeds when I run it locally. I'll push that change tomorrow with a test

That failing test (builder_works_post_deneb) is a bit weird and flaky, I'm guessing it could be related to one of these issues I had when I added this test here.

  • Use RUST_MIN_STACK=8388608: 4mb thread stack limit wasnt enough, looks like we really need to get @ethDreamer's Initial Attempt to Eliminate Blob Clones #4593 in.
  • Increase get_header timeout: 1 second timeout wasn't enough when running in debug - I think we might even want to override this in tests via env vars, as it's likely that mock builder requires more time to return a response.

Copy link
Member

@jimmygchen jimmygchen left a comment

Choose a reason for hiding this comment

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

I've re-reviewed the changes, looks good!

@jimmygchen
Copy link
Member

Oh, there seems to be some issues with expected withdrawals amount mismatch in the failing tests.

@michaelsproul
Copy link
Member Author

Yeah, looking into that now

@michaelsproul
Copy link
Member Author

Ok, I reverted the check that I added to the execution block hash generator, as it wasn't correct in the presence of slashable blocks.

The check I added was trying to verify that all payload attributes with the same head_block_hash, fee_recipient and timestamp were identical. This isn't the case when there are two chains of slashable blocks, e.g. at slot 9 & 10. The block roots of the blocks at slot 9 are distinct, but they both blocks have the same execution payload (and therefore identical execution block hash). Then when building the 2nd block at slot 10, the fork choice update has the same block hash as the first slot 10 block, but with a different parent root.

@michaelsproul michaelsproul added ready-for-merge This PR is ready to merge. and removed work-in-progress PR is a work-in-progress labels Sep 7, 2023
@michaelsproul michaelsproul merged commit 8db44de into sigp:deneb-free-blobs Sep 7, 2023
27 of 28 checks passed
@michaelsproul michaelsproul deleted the deneb-parent-block-root branch September 7, 2023 05:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deneb ready-for-merge This PR is ready to merge.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants