Try   HackMD

EPF Cohort 3 Dev Update 7 (pavignol)

Here are the Prysm validator features that I’ve been working on last week:

Wrote the REST implementation for Validator's GetDuties

While the beacon REST API separates the duties retrieval in 3 distinct endpoints (/eth/v1/validator/duties/attester/{epoch}, /eth/v1/validator/duties/proposer/{epoch} and /eth/v1/validator/duties/sync/{epoch}), the Prysm gRPC API does everything in a single function called GetDuties. Moreover, GetDuties automatically retrieves the duties for the current epoch and the next epoch while the beacon REST API endpoints only target a single epoch at a time. For these reasons, this endpoint required combining a lot of endpoints together and massaging the data to make it fit into a single giant data structure containing all duties for epoch and epoch+1.

To make sure that the mapping respected all requirements of the gRPC API, a few rules and details have to be kept in mind:

  1. Even validators that don't have duties for a given epoch should be returned if they were part of the request. This includes all validators in the pending state.
  2. Attester and sync duties should be retrieved for both epoch and epoch+1
  3. Proposer duties should only be retrieved for the current epoch (not epoch+1)
  4. Since sync committee duties are an Altair feature, they should only be retrieved for epoch>=AltairForkEpoch.
  5. For each validator, we have to return the array of validators that are part of the committee for the given epoch.
  6. In addition to the duties, we also have to return the status of each validator .

With those rules in mind, the implementation was relatively straightforward:

  1. Query the status of all validator public keys given in the input via the /eth/v1/beacon/states/head/validators endpoint to get the indices and status of each validator.
  2. Query the list of committees for the given epoch and cache its validators in a {committeeIndex, slot} -> validatorIndices map
  3. Query the list of attester duties for epoch and epoch+1 and cache them in a validatorIndex -> {committeeIndex, slot} map
  4. Query the list of sync duties for epoch and epoch+1 (if epoch>=AltairForkEpoch) and cache the validator indices that have a sync dutie for this epoch in a set
  5. Query the list of proposer duties for epoch and cache them in a validatorIndex -> slot map
  6. Finally, for each index obtained in step 1:
    6.1 If the attester duties map from step 3 has an entry for the current validator index, get its committee from the map obtained in step 2 and save the info in the output struct
    6.2 If the sync duties set from step 4 has an entry for the current validator index, set the IsSyncCommittee value of the output struct to true
    6.3 If the proposer duties map from step 5 has an entry for the current validator index, get its proposer slot from the map and set it in the output struct

Although the implementation is done and I have verified that it passes all tests, I haven't created a PR yet because it's dependent on 2 pending PRs:

Also, implementing this endpoint revealed bugs in the implementation of all 3 duties endpoint, where an epoch would be erroneously rejected because it was in the future. When the Prysm team comes back from the holidays break, I'll work with them to tackle this issue.

Going forward

Next week, I'm planning to implement the StreamBlocksAltair API. This is pretty exciting because it's the last endpoint that hasn't been assigned to someone yet, which means that all endpoints have either been merged into the develop branch, have a PR opened for them or are actively being worked on by an EPF fellow:

Legend:

Symbol State
:x: Not ready for PR
:o: PR opened
:heavy_check_mark: Merged into develop
Done Owner Endpoint
:x: pavignol GetDuties
:heavy_check_mark: pavignol GetBeaconBlock
:heavy_check_mark: pavignol ProposeBeaconBlock
:heavy_check_mark: pavignol PrepareBeaconProposer
:heavy_check_mark: pavignol GetAttestationData
:o: dhruv ProposeAttestation
:x: dhruv SubmitAggregateSelectionProof
:x: dhruv SubmitSignedAggregateSelectionProof
:heavy_check_mark: pavignol ProposeExit
:o: pavignol SubscribeCommitteeSubnets
:o: manu SubmitValidatorRegistrations
:heavy_check_mark: manu ValidatorIndex
:heavy_check_mark: manu ValidatorStatus
:o: manu MultipleValidatorStatus
:o: pavignol SubmitSignedContributionAndProof
:o: manu SubmitSyncMessage
:x: dhruv GetSyncSubcommitteeIndex
:x: dhruv GetSyncMessageBlockRoot
:x: pavignol StreamDuties
:heavy_check_mark: pavignol WaitForChainStart
:heavy_check_mark: manu WaitForActivation
:x: pavignol StreamBlocksAltair
:heavy_check_mark: pavignol DomainData
:x: manu GetFeeRecipientByPubKey
:x: manu CheckDoppelGanger
:x: dhruv GetSyncCommitteeContribution