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

Get the right head state when proposing a failed reorg #13579

Merged
merged 3 commits into from
Feb 5, 2024
Merged

Conversation

potuz
Copy link
Contributor

@potuz potuz commented Feb 2, 2024

This fixes the following bug:

The node is about to propose block N+1. It syncs block N, based on N-1, and is late, the node head remains being N-1 and will attempt a reorg. If at the beginning of the slot N+1 the node N has shown to be strong, the node relents and starts building a local payload immediately on top of N.

The node obtains the blockroot of N from forkchoice and requests the corresponding state advanced to N+1.
If the node also has a cache miss (in the NSC) then the node will advance the head state to N+1. Here's the bug since this would produce the state based from N-1, instead of N as we want.

cc @nisdas

@potuz potuz requested a review from a team as a code owner February 2, 2024 17:42
@potuz potuz added the Bug Something isn't working label Feb 2, 2024
Copy link
Member

@terencechain terencechain left a comment

Choose a reason for hiding this comment

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

Given the bug description and the amount of critical code changed, we might want to add a unit test for this one. It might not be easy though

nisdas
nisdas previously approved these changes Feb 3, 2024
head, err := vs.HeadFetcher.HeadState(ctx)
// process attestations and update head in forkchoice
vs.ForkchoiceFetcher.UpdateHead(ctx, vs.TimeFetcher.CurrentSlot())
headRoot := vs.ForkchoiceFetcher.CachedHeadRoot()
Copy link
Member

Choose a reason for hiding this comment

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

why not just derive the parent and head root in getParentHeadState and do all the checks in there ? You wouldn't need to call this in the main GetBeaconBlock method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's harder to test, but I can split it up in yet an extra layer.

@potuz potuz added this pull request to the merge queue Feb 5, 2024
nisdas
nisdas previously approved these changes Feb 5, 2024
@nisdas nisdas removed this pull request from the merge queue due to a manual request Feb 5, 2024
@nisdas nisdas dismissed their stale review February 5, 2024 12:27

new test

@potuz potuz enabled auto-merge February 5, 2024 12:30
if err != nil {
return nil, err
}
if head.Slot() >= slot {
Copy link
Member

Choose a reason for hiding this comment

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

this would be a failure condition, no ? You wouldn't be able to process the block if the head slot is more than our wanted slot

Copy link
Contributor Author

Choose a reason for hiding this comment

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

can never happen

@potuz potuz added this pull request to the merge queue Feb 5, 2024
Merged via the queue into develop with commit e2e7e84 Feb 5, 2024
17 checks passed
@potuz potuz deleted the proposer_bad_bet branch February 5, 2024 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants