Fix Doppelganger Check (#10582)

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
This commit is contained in:
Nishant Das 2022-04-30 01:19:43 +08:00 committed by GitHub
parent 84916672c6
commit ad03938964
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 13 deletions

View File

@ -141,7 +141,12 @@ func (vs *Server) CheckDoppelGanger(ctx context.Context, req *ethpb.DoppelGanger
// We request a state 32 slots ago. We are guaranteed to have
// currentSlot > 32 since we assume that we are in Altair's fork.
prevState, err := vs.ReplayerBuilder.ReplayerForSlot(headSlot - params.BeaconConfig().SlotsPerEpoch).ReplayBlocks(ctx)
prevStateSlot := headSlot - params.BeaconConfig().SlotsPerEpoch
prevEpochEnd, err := slots.EpochEnd(slots.ToEpoch(prevStateSlot))
if err != nil {
return nil, status.Error(codes.Internal, "Could not get previous epoch's end")
}
prevState, err := vs.ReplayerBuilder.ReplayerForSlot(prevEpochEnd).ReplayBlocks(ctx)
if err != nil {
return nil, status.Error(codes.Internal, "Could not get previous state")
}
@ -171,7 +176,7 @@ func (vs *Server) CheckDoppelGanger(ctx context.Context, req *ethpb.DoppelGanger
// ago, the current doppelganger check will not be able to
// identify dopplelgangers since an attestation can take up to
// 31 slots to be included.
if v.Epoch+1 >= currEpoch {
if v.Epoch+2 >= currEpoch {
resp.Responses = append(resp.Responses,
&ethpb.DoppelGangerResponse_ValidatorResponse{
PublicKey: v.PublicKey,
@ -376,8 +381,8 @@ func checkValidatorsAreRecent(headEpoch types.Epoch, req *ethpb.DoppelGangerRequ
// Due to how balances are reflected for individual
// validators, we can only effectively determine if a
// validator voted or not if we are able to look
// back more than 1 epoch into the past.
if v.Epoch+1 < headEpoch {
// back more than 2 epoch into the past.
if v.Epoch+2 < headEpoch {
validatorsAreRecent = false
// Zero out response if we encounter non-recent validators to
// guard against potential misuse.

View File

@ -961,7 +961,7 @@ func TestServer_CheckDoppelGanger(t *testing.T) {
svSetup: func(t *testing.T) (*Server, *ethpb.DoppelGangerRequest, *ethpb.DoppelGangerResponse) {
hs, ps, keys := createStateSetupAltair(t, 3)
rb := mockstategen.NewMockReplayerBuilder()
rb.SetMockStateForSlot(ps, 20)
rb.SetMockStateForSlot(ps, 23)
vs := &Server{
HeadFetcher: &mockChain.ChainService{
State: hs,
@ -993,7 +993,7 @@ func TestServer_CheckDoppelGanger(t *testing.T) {
svSetup: func(t *testing.T) (*Server, *ethpb.DoppelGangerRequest, *ethpb.DoppelGangerResponse) {
hs, ps, keys := createStateSetupAltair(t, 3)
rb := mockstategen.NewMockReplayerBuilder()
rb.SetMockStateForSlot(ps, 20)
rb.SetMockStateForSlot(ps, 23)
currentIndices := make([]byte, 64)
currentIndices[2] = 1
require.NoError(t, hs.SetCurrentParticipationBits(currentIndices))
@ -1024,7 +1024,7 @@ func TestServer_CheckDoppelGanger(t *testing.T) {
// Add in for duplicate validator
request.ValidatorRequests = append(request.ValidatorRequests, &ethpb.DoppelGangerRequest_ValidatorRequest{
PublicKey: keys[2].PublicKey().Marshal(),
Epoch: 1,
Epoch: 0,
SignedRoot: []byte{'A'},
})
response.Responses = append(response.Responses, &ethpb.DoppelGangerResponse_ValidatorResponse{
@ -1043,7 +1043,7 @@ func TestServer_CheckDoppelGanger(t *testing.T) {
prevIndices[2] = 1
require.NoError(t, ps.SetPreviousParticipationBits(prevIndices))
rb := mockstategen.NewMockReplayerBuilder()
rb.SetMockStateForSlot(ps, 20)
rb.SetMockStateForSlot(ps, 23)
vs := &Server{
HeadFetcher: &mockChain.ChainService{
@ -1071,7 +1071,7 @@ func TestServer_CheckDoppelGanger(t *testing.T) {
// Add in for duplicate validator
request.ValidatorRequests = append(request.ValidatorRequests, &ethpb.DoppelGangerRequest_ValidatorRequest{
PublicKey: keys[2].PublicKey().Marshal(),
Epoch: 1,
Epoch: 0,
SignedRoot: []byte{'A'},
})
response.Responses = append(response.Responses, &ethpb.DoppelGangerResponse_ValidatorResponse{
@ -1091,7 +1091,7 @@ func TestServer_CheckDoppelGanger(t *testing.T) {
currentIndices[11] = 2
require.NoError(t, hs.SetPreviousParticipationBits(currentIndices))
rb := mockstategen.NewMockReplayerBuilder()
rb.SetMockStateForSlot(ps, 20)
rb.SetMockStateForSlot(ps, 23)
prevIndices := make([]byte, 64)
for i := 12; i < 20; i++ {
@ -1114,7 +1114,7 @@ func TestServer_CheckDoppelGanger(t *testing.T) {
// Add in for duplicate validator
request.ValidatorRequests = append(request.ValidatorRequests, &ethpb.DoppelGangerRequest_ValidatorRequest{
PublicKey: keys[i].PublicKey().Marshal(),
Epoch: 1,
Epoch: 0,
SignedRoot: []byte{'A'},
})
response.Responses = append(response.Responses, &ethpb.DoppelGangerResponse_ValidatorResponse{
@ -1143,8 +1143,11 @@ func TestServer_CheckDoppelGanger(t *testing.T) {
svSetup: func(t *testing.T) (*Server, *ethpb.DoppelGangerRequest, *ethpb.DoppelGangerResponse) {
hs, ps, keys := createStateSetupAltair(t, 3)
rb := mockstategen.NewMockReplayerBuilder()
rb.SetMockStateForSlot(ps, 20)
rb.SetMockStateForSlot(ps, 23)
currentIndices := make([]byte, 64)
currentIndices[0] = 1
currentIndices[1] = 2
require.NoError(t, hs.SetPreviousParticipationBits(currentIndices))
vs := &Server{
HeadFetcher: &mockChain.ChainService{
State: hs,
@ -1171,6 +1174,43 @@ func TestServer_CheckDoppelGanger(t *testing.T) {
return vs, request, response
},
},
{
name: "attesters are too recent(previous state)",
wantErr: false,
svSetup: func(t *testing.T) (*Server, *ethpb.DoppelGangerRequest, *ethpb.DoppelGangerResponse) {
hs, ps, keys := createStateSetupAltair(t, 3)
rb := mockstategen.NewMockReplayerBuilder()
rb.SetMockStateForSlot(ps, 23)
currentIndices := make([]byte, 64)
currentIndices[0] = 1
currentIndices[1] = 2
require.NoError(t, ps.SetPreviousParticipationBits(currentIndices))
vs := &Server{
HeadFetcher: &mockChain.ChainService{
State: hs,
},
SyncChecker: &mockSync.Sync{IsSyncing: false},
ReplayerBuilder: rb,
}
request := &ethpb.DoppelGangerRequest{
ValidatorRequests: make([]*ethpb.DoppelGangerRequest_ValidatorRequest, 0),
}
response := &ethpb.DoppelGangerResponse{Responses: make([]*ethpb.DoppelGangerResponse_ValidatorResponse, 0)}
for i := 0; i < 15; i++ {
request.ValidatorRequests = append(request.ValidatorRequests, &ethpb.DoppelGangerRequest_ValidatorRequest{
PublicKey: keys[i].PublicKey().Marshal(),
Epoch: 1,
SignedRoot: []byte{'A'},
})
response.Responses = append(response.Responses, &ethpb.DoppelGangerResponse_ValidatorResponse{
PublicKey: keys[i].PublicKey().Marshal(),
DuplicateExists: false,
})
}
return vs, request, response
},
},
{
name: "exit early for Phase 0",
wantErr: false,