-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Conversation
This situation can never happen |
Messed up on the graph. I meant:
|
This also can't happen :) |
s.headLock.RLock() | ||
if newHeadRoot == [32]byte{} || s.headRoot() == newHeadRoot { | ||
if newHeadRoot == [32]byte{} || s.headRoot() == newHeadRoot && !ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if newHeadRoot == [32]byte{} || s.headRoot() == newHeadRoot && !ok { | |
if newHeadRoot == [32]byte{} || s.headRoot() == newHeadRoot && ok { |
…nto fcu-with-attribute
return ok | ||
} | ||
|
||
func (s *Service) isNewHead(r [32]byte) bool { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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{}
In the following condition:
you are a proposer for
102
, and101
arrived on time but never became head. The head during101
was still100
. Under such conditions, we want to call FCU with head100
and payload attribute as soon as we process101
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 of102
This PR:
notifyEngineIfChangedHead
toforkchoiceUpdateWithExecution
. More align on namingforkchoice_update_execution.go
forkchoice_update_execution_test.go
TestService_forkchoiceUpdateWithExecution_SameHeadRootNewProposer