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

Allow fetching sync committee duties for current and next period's epochs #9728

Merged
merged 9 commits into from
Oct 5, 2021

Conversation

rkapka
Copy link
Contributor

@rkapka rkapka commented Oct 4, 2021

What type of PR is this?

Bug fix

What does this PR do? Why is it needed?

https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Validator/getSyncCommitteeDuties describes the epoch parameter as

epoch // EPOCHS_PER_SYNC_COMMITTEE_PERIOD <= current_epoch // EPOCHS_PER_SYNC_COMMITTEE_PERIOD + 1

This means that any epoch from the current or next sync committee period is valid.

Which issues(s) does this PR fix?

Fixes #9720

@rkapka rkapka added the API Api related tasks label Oct 4, 2021
@rkapka rkapka requested a review from a team as a code owner October 4, 2021 16:32
@rkapka rkapka requested review from kasey, jmozah and nisdas October 4, 2021 16:32
@@ -398,6 +434,19 @@ func TestGetSyncCommitteeDuties_SyncNotReady(t *testing.T) {
assert.ErrorContains(t, "Syncing to latest head, not ready to respond", err)
}

func TestSyncCommitteeDutiesLastValidEpoch(t *testing.T) {
Copy link
Contributor Author

@rkapka rkapka Oct 4, 2021

Choose a reason for hiding this comment

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

I don't particularly like this test because it duplicates a part of the implementation. But because I fetch a config value, which changes between regular and minimal configs, I cannot simply hardcode a number here.

@@ -175,45 +186,55 @@ func (vs *Server) GetSyncCommitteeDuties(ctx context.Context, req *ethpbv2.SyncC
return nil, status.Error(codes.Unavailable, "Syncing to latest head, not ready to respond")
}

slot, err := slots.EpochStart(req.Epoch)
currentSlot := slots.CurrentSlot(uint64(vs.TimeFetcher.GenesisTime().Unix()))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
currentSlot := slots.CurrentSlot(uint64(vs.TimeFetcher.GenesisTime().Unix()))
currentSlot := vs.TimeFetcher.CurrentSlot()


var stateEpoch types.Epoch
// Integer division and multiplication do not cancel out.
currentSyncCommitteeFirstEpoch := (currentEpoch / params.BeaconConfig().EpochsPerSyncCommitteePeriod) * params.BeaconConfig().EpochsPerSyncCommitteePeriod
Copy link
Member

Choose a reason for hiding this comment

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

please use slots.SyncCommitteePeriodStartEpoch. It also uses SafeMul

if req.Epoch >= currentSyncCommitteeFirstEpoch {
stateEpoch = currentSyncCommitteeFirstEpoch
} else {
stateEpoch = req.Epoch
Copy link
Member

Choose a reason for hiding this comment

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

this is not correct, stateEpoch should be slots.SyncCommitteePeriodStartEpoch(req.epoch)

Copy link
Contributor Author

@rkapka rkapka Oct 4, 2021

Choose a reason for hiding this comment

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

Does it make a difference? Won't duties be the same throughout the whole period because of the same committees returned from the state? I will change this to what you recommend either way.

Copy link
Member

Choose a reason for hiding this comment

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

it wont make a difference here as i read through the function, luckily we are just getting the committee from the state, we are not sampling the committee. To sample the committee, we should always use the epoch boundary state as described here ethereum/consensus-specs#2394

Comment on lines 195 to 209

var stateEpoch types.Epoch
currentSyncCommitteeFirstEpoch, err := slots.SyncCommitteePeriodStartEpoch(currentEpoch / params.BeaconConfig().EpochsPerSyncCommitteePeriod)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "Could not get sync committee period start epoch: %v.", err)
}
if req.Epoch >= currentSyncCommitteeFirstEpoch {
stateEpoch = currentSyncCommitteeFirstEpoch
} else {
stateEpoch, err = slots.SyncCommitteePeriodStartEpoch(req.Epoch)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "Could not get sync committee period start epoch: %v.", err)
}
}
slot, err := slots.EpochStart(stateEpoch)
Copy link
Member

@terencechain terencechain Oct 5, 2021

Choose a reason for hiding this comment

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

Final feedback. No need for the fancier if else condition. Since we already verified req.Epoch > lastValidEpoch, the following should be work

Suggested change
var stateEpoch types.Epoch
currentSyncCommitteeFirstEpoch, err := slots.SyncCommitteePeriodStartEpoch(currentEpoch / params.BeaconConfig().EpochsPerSyncCommitteePeriod)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "Could not get sync committee period start epoch: %v.", err)
}
if req.Epoch >= currentSyncCommitteeFirstEpoch {
stateEpoch = currentSyncCommitteeFirstEpoch
} else {
stateEpoch, err = slots.SyncCommitteePeriodStartEpoch(req.Epoch)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "Could not get sync committee period start epoch: %v.", err)
}
}
slot, err := slots.EpochStart(stateEpoch)
requestedEpoch := req.Epoch
if requestedEpoch > currentEpoch {
requestedEpoch = currentEpoch
}
slot, err := slots.EpochStart(requestedEpoch)

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.

Nice!

@terencechain terencechain merged commit 9aa5035 into develop Oct 5, 2021
@delete-merged-branch delete-merged-branch bot deleted the sync-duties-future-epoch branch October 5, 2021 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Api related tasks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

/eth/v1/validator/duties/sync does not handle future slot
2 participants