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

Call FCU with attribute on non head block #11919

Merged
merged 18 commits into from
Jan 31, 2023
Merged

Conversation

terencechain
Copy link
Member

@terencechain terencechain commented Jan 25, 2023

In the following condition:

99 - 100
   \-- 101

you are a proposer for 102, and 101 arrived on time but never became head. The head during 101 was still 100. Under such conditions, we want to call FCU with head 100 and payload attribute as soon as we process 101 to signal EL client for payload preparation. If we don't do this, then the proposer will wait to call FCU with payload attribute at the start of 102

This PR:

  • Reimplement notifyEngineIfChangedHead to forkchoiceUpdateWithExecution. More align on naming
  • Refactored all the necessary logic under forkchoice_update_execution.go
  • Refactored all the necessary tests under forkchoice_update_execution_test.go
  • Added a new test TestService_forkchoiceUpdateWithExecution_SameHeadRootNewProposer

@terencechain terencechain self-assigned this Jan 25, 2023
@potuz
Copy link
Contributor

potuz commented Jan 25, 2023

In the following condition, 100 <- 101 <- 102, you are a proposer for 102, and 101 arrived on time but never became head.

This situation can never happen

@terencechain
Copy link
Member Author

In the following condition, 100 <- 101 <- 102, you are a proposer for 102, and 101 arrived on time but never became head.

This situation can never happen

Messed up on the graph. I meant:

100 /--- 101
    \--- 102

@potuz
Copy link
Contributor

potuz commented Jan 25, 2023

In the following condition, 100 <- 101 <- 102, you are a proposer for 102, and 101 arrived on time but never became head.

This situation can never happen

Messed up on the graph. I meant:

100 /--- 101
    \--- 102

This also can't happen :)

@terencechain terencechain added Bug Something isn't working Priority: High High priority item labels Jan 26, 2023
s.headLock.RLock()
if newHeadRoot == [32]byte{} || s.headRoot() == newHeadRoot {
if newHeadRoot == [32]byte{} || s.headRoot() == newHeadRoot && !ok {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if newHeadRoot == [32]byte{} || s.headRoot() == newHeadRoot && !ok {
if newHeadRoot == [32]byte{} || s.headRoot() == newHeadRoot && ok {

@terencechain terencechain marked this pull request as ready for review January 28, 2023 07:39
@terencechain terencechain requested a review from a team as a code owner January 28, 2023 07:39
return ok
}

func (s *Service) isNewHead(r [32]byte) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

This adds duplicated logic in a few places. At the very least I remember saveHead where the same check its used. If we are going to have a dedicated method to check if a given block root differs from the stored head, we should move these checks to use this method.

Also, the logic in saveHead is a little safer with respect to the origin Root, so I'll extend slightly this comment. This is what saveHead currently has:

func (s *Service) saveHead(ctx context.Context, newHeadRoot [32]byte, headBlock interfaces.SignedBeaconBlock, headState state.BeaconState) error {
...
	var oldHeadRoot [32]byte
	s.headLock.RLock()
	if s.head == nil {
		oldHeadRoot = s.originBlockRoot
	} else {
		oldHeadRoot = s.head.root
	}
	s.headLock.RUnlock()
	if newHeadRoot == oldHeadRoot {
		return nil
	}

We should move the last check to

if s.isNewHead(newHeadRoot)

But also, we should probably add the checks for head being nil and dealing with the originBlockRoot in this method as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done. One annoying part is we still need to retrieve oldHeadRoot for logs

return r == [32]byte{} || r != s.headRoot()
}

func (s *Service) getHeadStateAndBlock(ctx context.Context, r [32]byte) (state.BeaconState, interfaces.SignedBeaconBlock, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This function name is very misleading as it does not get the head state and block, but rather any state and block with the passed block root r.

return err
}

if err := s.saveHead(ctx, newHeadRoot, headBlock, headState); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

This will again repeat the check for isNewHead in saveHead when we could have saved the result in the first line of this method. It would be better to change the semanthics of saveHead to not make this check, so that it actually is like the name indicates, a function that saves head, instead of the currently misleading saveHeadIfNew. This would require starting this method with something like

        newHead := s.isNewHead(newHeadRoot)
	if !newHead && !s.isNewProposer() {
		return nil
	}
	....
	if newHead {
		if err := s.saveHead(ctx, newHeadRoot, headBlock, headState); err != nil {
         ...
     }

currentHeadRoot = s.headRoot()
}

return r == [32]byte{} || r != currentHeadRoot
Copy link
Contributor

Choose a reason for hiding this comment

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

I know I'm a pain in the butt but can we shift the logic:

return  r != currentHeadRoot || r == [32]byte{}

potuz
potuz previously approved these changes Jan 31, 2023
@potuz potuz removed the OK to merge label Jan 31, 2023
@prylabs-bulldozer prylabs-bulldozer bot merged commit c070283 into develop Jan 31, 2023
@delete-merged-branch delete-merged-branch bot deleted the fcu-with-attribute branch January 31, 2023 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working Priority: High High priority item
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants