Allow proposer duties one epoch in advance part 2 (#11818)

Co-authored-by: rkapka <rkapka@wp.pl>
This commit is contained in:
terencechain
2022-12-23 06:00:36 +08:00
committed by GitHub
parent 4d549f572c
commit dac555a57c
2 changed files with 64 additions and 16 deletions

View File

@@ -138,27 +138,38 @@ func (vs *Server) GetProposerDuties(ctx context.Context, req *ethpbv1.ProposerDu
return nil, err
}
cs := vs.TimeFetcher.CurrentSlot()
currentEpoch := slots.ToEpoch(cs)
if req.Epoch > currentEpoch {
return nil, status.Errorf(codes.InvalidArgument, "Request epoch %d can not be greater than current epoch %d", req.Epoch, currentEpoch)
}
isOptimistic, err := vs.OptimisticModeFetcher.IsOptimistic(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check optimistic status: %v", err)
}
cs := vs.TimeFetcher.CurrentSlot()
currentEpoch := slots.ToEpoch(cs)
nextEpoch := currentEpoch + 1
var nextEpochLookahead bool
if req.Epoch > nextEpoch {
return nil, status.Errorf(codes.InvalidArgument, "Request epoch %d can not be greater than next epoch %d", req.Epoch, currentEpoch+1)
} else if req.Epoch == nextEpoch {
// If the request is for the next epoch, we use the current epoch's state to compute duties.
req.Epoch = currentEpoch
nextEpochLookahead = true
}
startSlot, err := slots.EpochStart(req.Epoch)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get start slot from epoch: %v", err)
return nil, status.Errorf(codes.Internal, "Could not get start slot from epoch %d: %v", req.Epoch, err)
}
s, err := vs.StateFetcher.StateBySlot(ctx, startSlot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
}
_, proposals, err := helpers.CommitteeAssignments(ctx, s, req.Epoch)
var proposals map[types.ValidatorIndex][]types.Slot
if nextEpochLookahead {
_, proposals, err = helpers.CommitteeAssignments(ctx, s, nextEpoch)
} else {
_, proposals, err = helpers.CommitteeAssignments(ctx, s, req.Epoch)
}
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not compute committee assignments: %v", err)
}
@@ -189,11 +200,7 @@ func (vs *Server) GetProposerDuties(ctx context.Context, req *ethpbv1.ProposerDu
return nil, status.Errorf(codes.Internal, "Could not get dependent root: %v", err)
}
slot, err := slots.EpochStart(req.Epoch)
if err != nil {
return nil, err
}
vs.ProposerSlotIndexCache.PrunePayloadIDs(slot)
vs.ProposerSlotIndexCache.PrunePayloadIDs(startSlot)
return &ethpbv1.ProposerDutiesResponse{
DependentRoot: root,

View File

@@ -235,6 +235,8 @@ func TestGetProposerDuties(t *testing.T) {
require.NoError(t, err, "Could not get signing root")
roots := make([][]byte, fieldparams.BlockRootsLength)
roots[0] = genesisRoot[:]
// We DON'T WANT this root to be returned when testing the next epoch
roots[31] = []byte("next_epoch_dependent_root")
db := dbutil.SetupDB(t)
pubKeys := make([][]byte, len(deposits))
@@ -282,12 +284,51 @@ func TestGetProposerDuties(t *testing.T) {
assert.DeepEqual(t, pubKeys[9982], expectedDuty.Pubkey)
})
t.Run("Next epoch", func(t *testing.T) {
bs, err := transition.GenesisBeaconState(context.Background(), deposits, 0, eth1Data)
require.NoError(t, err, "Could not set up genesis state")
require.NoError(t, bs.SetBlockRoots(roots))
chainSlot := types.Slot(0)
chain := &mockChain.ChainService{
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
}
vs := &Server{
StateFetcher: &testutil.MockFetcher{StatesBySlot: map[types.Slot]state.BeaconState{0: bs}},
HeadFetcher: chain,
TimeFetcher: chain,
OptimisticModeFetcher: chain,
SyncChecker: &mockSync.Sync{IsSyncing: false},
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
}
req := &ethpbv1.ProposerDutiesRequest{
Epoch: 1,
}
resp, err := vs.GetProposerDuties(ctx, req)
require.NoError(t, err)
assert.DeepEqual(t, bytesutil.PadTo(genesisRoot[:], 32), resp.DependentRoot)
assert.Equal(t, 32, len(resp.Data))
// We expect a proposer duty for slot 43.
var expectedDuty *ethpbv1.ProposerDuty
for _, duty := range resp.Data {
if duty.Slot == 43 {
expectedDuty = duty
}
}
vid, _, has := vs.ProposerSlotIndexCache.GetProposerPayloadIDs(43, [32]byte{})
require.Equal(t, true, has)
require.Equal(t, types.ValidatorIndex(4863), vid)
require.NotNil(t, expectedDuty, "Expected duty for slot 43 not found")
assert.Equal(t, types.ValidatorIndex(4863), expectedDuty.ValidatorIndex)
assert.DeepEqual(t, pubKeys[4863], expectedDuty.Pubkey)
})
t.Run("Prune payload ID cache ok", func(t *testing.T) {
bs, err := transition.GenesisBeaconState(context.Background(), deposits, 0, eth1Data)
require.NoError(t, err, "Could not set up genesis state")
require.NoError(t, bs.SetSlot(params.BeaconConfig().SlotsPerEpoch))
require.NoError(t, bs.SetBlockRoots(roots))
chainSlot := types.Slot(params.BeaconConfig().SlotsPerEpoch)
chainSlot := params.BeaconConfig().SlotsPerEpoch
chain := &mockChain.ChainService{
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
}
@@ -342,11 +383,11 @@ func TestGetProposerDuties(t *testing.T) {
currentEpoch := slots.ToEpoch(bs.Slot())
req := &ethpbv1.ProposerDutiesRequest{
Epoch: currentEpoch + 1,
Epoch: currentEpoch + 2,
}
_, err = vs.GetProposerDuties(ctx, req)
require.NotNil(t, err)
assert.ErrorContains(t, fmt.Sprintf("Request epoch %d can not be greater than current epoch %d", currentEpoch+1, currentEpoch), err)
assert.ErrorContains(t, fmt.Sprintf("Request epoch %d can not be greater than next epoch %d", currentEpoch+2, currentEpoch+1), err)
})
t.Run("execution optimistic", func(t *testing.T) {