-
Notifications
You must be signed in to change notification settings - Fork 994
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
HTTP endpoint for GetValidatorParticipation
#14261
Merged
Merged
Changes from 9 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
cbec3bb
add endpoint
saolyn 600bcdf
remove canonicalFetcher
saolyn a7f1b89
Add replayerBuilder to coreService
saolyn 9509f76
fix endpoint template
saolyn 84918bf
fix string query params
saolyn 95eb96c
gaz
saolyn f5eb19a
fix linter
saolyn 96e387c
Merge branch 'develop' into http-validator-participation
saolyn 01cb892
test fix
rkapka a8f8e7d
Radek' review
saolyn 409b0af
remove unused request struct + gaz
saolyn fbc488c
Merge branch 'develop' into http-validator-participation
saolyn 976b3d7
linter
saolyn 3e15162
gaz
saolyn 5c4a8ab
Merge branch 'develop' into http-validator-participation
rkapka File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -752,3 +752,87 @@ func subnetsFromCommittee(pubkey []byte, comm *ethpb.SyncCommittee) []uint64 { | |||||
} | ||||||
return positions | ||||||
} | ||||||
|
||||||
// ValidatorParticipation retrieves the validator participation information for a given epoch, | ||||||
// it returns the information about validator's participation rate in voting on the proof of stake | ||||||
// rules based on their balance compared to the total active validator balance. | ||||||
func (s *Service) ValidatorParticipation( | ||||||
ctx context.Context, | ||||||
requestedEpoch primitives.Epoch, | ||||||
) ( | ||||||
*ethpb.ValidatorParticipationResponse, | ||||||
*RpcError, | ||||||
) { | ||||||
currentSlot := s.GenesisTimeFetcher.CurrentSlot() | ||||||
currentEpoch := slots.ToEpoch(currentSlot) | ||||||
|
||||||
if requestedEpoch > currentEpoch { | ||||||
return nil, &RpcError{ | ||||||
Err: fmt.Errorf("cannot retrieve information about an epoch greater than current epoch, current epoch %d, requesting %d", currentEpoch, requestedEpoch), | ||||||
Reason: BadRequest, | ||||||
} | ||||||
} | ||||||
// Use the last slot of requested epoch to obtain current and previous epoch attestations. | ||||||
// This ensures that we don't miss previous attestations when input requested epochs. | ||||||
endSlot, err := slots.EpochEnd(requestedEpoch) | ||||||
if err != nil { | ||||||
return nil, &RpcError{Reason: Internal, Err: errors.Wrap(err, "could not get slot from requested epoch")} | ||||||
} | ||||||
// Get as close as we can to the end of the current epoch without going past the current slot. | ||||||
// The above check ensures a future *epoch* isn't requested, but the end slot of the requested epoch could still | ||||||
// be past the current slot. In that case, use the current slot as the best approximation of the requested epoch. | ||||||
// Replayer will make sure the slot ultimately used is canonical. | ||||||
if endSlot > currentSlot { | ||||||
endSlot = currentSlot | ||||||
} | ||||||
|
||||||
// ReplayerBuilder ensures that a canonical chain is followed to the slot | ||||||
beaconSt, err := s.ReplayerBuilder.ReplayerForSlot(endSlot).ReplayBlocks(ctx) | ||||||
if err != nil { | ||||||
return nil, &RpcError{Reason: Internal, Err: errors.Wrapf(err, "error replaying blocks for state at slot %d", endSlot)} | ||||||
} | ||||||
var v []*precompute.Validator | ||||||
var b *precompute.Balance | ||||||
|
||||||
if beaconSt.Version() == version.Phase0 { | ||||||
v, b, err = precompute.New(ctx, beaconSt) | ||||||
if err != nil { | ||||||
return nil, &RpcError{Reason: Internal, Err: errors.Wrap(err, "could not set up pre compute instance")} | ||||||
} | ||||||
_, b, err = precompute.ProcessAttestations(ctx, beaconSt, v, b) | ||||||
if err != nil { | ||||||
return nil, &RpcError{Reason: Internal, Err: errors.Wrap(err, "could not pre compute attestations")} | ||||||
} | ||||||
} else if beaconSt.Version() >= version.Altair { | ||||||
v, b, err = altair.InitializePrecomputeValidators(ctx, beaconSt) | ||||||
if err != nil { | ||||||
return nil, &RpcError{Reason: Internal, Err: errors.Wrap(err, "could not set up altair pre compute instance")} | ||||||
} | ||||||
_, b, err = altair.ProcessEpochParticipation(ctx, beaconSt, b, v) | ||||||
if err != nil { | ||||||
return nil, &RpcError{Reason: Internal, Err: errors.Wrap(err, "could not pre compute attestations: %v")} | ||||||
} | ||||||
} else { | ||||||
return nil, &RpcError{Reason: Internal, Err: fmt.Errorf("invalid state type retrieved with a version of %d", beaconSt.Version())} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
cp := s.FinalizedFetcher.FinalizedCheckpt() | ||||||
p := ðpb.ValidatorParticipationResponse{ | ||||||
Epoch: requestedEpoch, | ||||||
Finalized: requestedEpoch <= cp.Epoch, | ||||||
Participation: ðpb.ValidatorParticipation{ | ||||||
// TODO(7130): Remove these three deprecated fields. | ||||||
GlobalParticipationRate: float32(b.PrevEpochTargetAttested) / float32(b.ActivePrevEpoch), | ||||||
VotedEther: b.PrevEpochTargetAttested, | ||||||
EligibleEther: b.ActivePrevEpoch, | ||||||
CurrentEpochActiveGwei: b.ActiveCurrentEpoch, | ||||||
CurrentEpochAttestingGwei: b.CurrentEpochAttested, | ||||||
CurrentEpochTargetAttestingGwei: b.CurrentEpochTargetAttested, | ||||||
PreviousEpochActiveGwei: b.ActivePrevEpoch, | ||||||
PreviousEpochAttestingGwei: b.PrevEpochAttested, | ||||||
PreviousEpochTargetAttestingGwei: b.PrevEpochTargetAttested, | ||||||
PreviousEpochHeadAttestingGwei: b.PrevEpochHeadAttested, | ||||||
}, | ||||||
} | ||||||
return p, nil | ||||||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1060,9 +1060,10 @@ func (s *Service) prysmNodeEndpoints() []endpoint { | |
} | ||
} | ||
|
||
func (*Service) prysmValidatorEndpoints(coreService *core.Service) []endpoint { | ||
func (s *Service) prysmValidatorEndpoints(coreService *core.Service) []endpoint { | ||
server := &validatorprysm.Server{ | ||
CoreService: coreService, | ||
ChainInfoFetcher: s.cfg.ChainInfoFetcher, | ||
CoreService: coreService, | ||
} | ||
|
||
const namespace = "prysm.validator" | ||
|
@@ -1087,5 +1088,15 @@ func (*Service) prysmValidatorEndpoints(coreService *core.Service) []endpoint { | |
handler: server.GetValidatorPerformance, | ||
methods: []string{http.MethodPost}, | ||
}, | ||
{ | ||
template: "/prysm/v1/validators/participation", | ||
name: namespace + ".GetValidatorParticipation", | ||
middleware: []mux.MiddlewareFunc{ | ||
middleware.ContentTypeHandler([]string{api.JsonMediaType}), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not needed for GET |
||
middleware.AcceptHeaderHandler([]string{api.JsonMediaType}), | ||
}, | ||
handler: server.GetValidatorParticipation, | ||
methods: []string{http.MethodGet}, | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Looks like you do not ever read the
epoch
parameter in the handler and rely onstate_id
instead. This makes sense to me but:epoch
param if we ignore it anyway; otherwise it will confuse callersstate_id
in the same way as in Beacon API handlers; this means using theStater
to fetch states, which allows us to pass the following into the param: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.
We do use the epoch, I set it to prioritize the
state_id
if it's set but it isn't required so in the default case wherestate_id
doesn't match anything we set the epoch which is technically required in this case so thatelse
I have doesn't actually do anything and would need to be removed here, or just remove therequired
: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.
Ah OK, I missed it. I don't have that strong of an opinion on this, but having just a
state_id
and using theStater
similarly to how we do it in Beacon API makes things simpler and more uniform.