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

Add capella cases for RPC calls #11759

Merged
merged 9 commits into from
Dec 14, 2022
23 changes: 12 additions & 11 deletions beacon-chain/rpc/prysm/v1alpha1/beacon/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,8 +518,8 @@ func (bs *Server) GetValidatorParticipation(
}
var v []*precompute.Validator
var b *precompute.Balance
switch beaconState.Version() {
case version.Phase0:

if beaconState.Version() == version.Phase0 {
v, b, err = precompute.New(ctx, beaconState)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not set up pre compute instance: %v", err)
Expand All @@ -528,7 +528,7 @@ func (bs *Server) GetValidatorParticipation(
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not pre compute attestations: %v", err)
}
case version.Altair, version.Bellatrix:
} else if beaconState.Version() >= version.Altair {
v, b, err = altair.InitializePrecomputeValidators(ctx, beaconState)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not set up altair pre compute instance: %v", err)
Expand All @@ -537,9 +537,10 @@ func (bs *Server) GetValidatorParticipation(
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not pre compute attestations: %v", err)
}
default:
} else {
return nil, status.Errorf(codes.Internal, "Invalid state type retrieved with a version of %d", beaconState.Version())
}

cp := bs.FinalizationFetcher.FinalizedCheckpt()
p := &ethpb.ValidatorParticipationResponse{
Epoch: requestedEpoch,
Expand Down Expand Up @@ -678,8 +679,7 @@ func (bs *Server) GetValidatorPerformance(
}
}
var validatorSummary []*precompute.Validator
switch headState.Version() {
case version.Phase0:
if headState.Version() == version.Phase0 {
vp, bp, err := precompute.New(ctx, headState)
if err != nil {
return nil, err
Expand All @@ -693,7 +693,7 @@ func (bs *Server) GetValidatorPerformance(
return nil, err
}
validatorSummary = vp
case version.Altair, version.Bellatrix:
} else if headState.Version() >= version.Altair {
vp, bp, err := altair.InitializePrecomputeValidators(ctx, headState)
if err != nil {
return nil, err
Expand All @@ -711,6 +711,8 @@ func (bs *Server) GetValidatorPerformance(
return nil, err
}
validatorSummary = vp
} else {
return nil, status.Errorf(codes.Internal, "Head state version %d not supported", headState.Version())
}

responseCap := len(req.Indices) + len(req.PublicKeys)
Expand Down Expand Up @@ -855,8 +857,7 @@ func (bs *Server) GetIndividualVotes(

var v []*precompute.Validator
var bal *precompute.Balance
switch st.Version() {
case version.Phase0:
if st.Version() == version.Phase0 {
v, bal, err = precompute.New(ctx, st)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not set up pre compute instance: %v", err)
Expand All @@ -865,7 +866,7 @@ func (bs *Server) GetIndividualVotes(
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not pre compute attestations: %v", err)
}
case version.Altair, version.Bellatrix:
} else if st.Version() >= version.Altair {
v, bal, err = altair.InitializePrecomputeValidators(ctx, st)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not set up altair pre compute instance: %v", err)
Expand All @@ -874,7 +875,7 @@ func (bs *Server) GetIndividualVotes(
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not pre compute attestations: %v", err)
}
default:
} else {
return nil, status.Errorf(codes.Internal, "Invalid state type retrieved with a version of %d", st.Version())
}

Expand Down
174 changes: 174 additions & 0 deletions beacon-chain/rpc/prysm/v1alpha1/beacon/validators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1704,6 +1704,24 @@ func TestServer_GetValidatorParticipation_CurrentAndPrevEpochWithBits(t *testing
assert.NoError(t, err)
runGetValidatorParticipationCurrentAndPrevEpoch(t, genState, gb)
})

t.Run("capella", func(t *testing.T) {
validatorCount := uint64(32)
genState, _ := util.DeterministicGenesisStateCapella(t, validatorCount)
c, err := altair.NextSyncCommittee(context.Background(), genState)
require.NoError(t, err)
require.NoError(t, genState.SetCurrentSyncCommittee(c))

bits := make([]byte, validatorCount)
for i := range bits {
bits[i] = 0xff
}
require.NoError(t, genState.SetCurrentParticipationBits(bits))
require.NoError(t, genState.SetPreviousParticipationBits(bits))
gb, err := blocks.NewSignedBeaconBlock(util.NewBeaconBlockCapella())
assert.NoError(t, err)
runGetValidatorParticipationCurrentAndPrevEpoch(t, genState, gb)
})
}

func runGetValidatorParticipationCurrentAndPrevEpoch(t *testing.T, genState state.BeaconState, gb interfaces.SignedBeaconBlock) {
Expand Down Expand Up @@ -2141,6 +2159,74 @@ func TestGetValidatorPerformanceBellatrix_OK(t *testing.T) {
}
}

func TestGetValidatorPerformanceCapella_OK(t *testing.T) {
helpers.ClearCache()
params.SetupTestConfigCleanup(t)
params.OverrideBeaconConfig(params.MinimalSpecConfig())

ctx := context.Background()
epoch := types.Epoch(1)
headState, _ := util.DeterministicGenesisStateCapella(t, 32)
require.NoError(t, headState.SetSlot(params.BeaconConfig().SlotsPerEpoch.Mul(uint64(epoch+1))))

defaultBal := params.BeaconConfig().MaxEffectiveBalance
extraBal := params.BeaconConfig().MaxEffectiveBalance + params.BeaconConfig().GweiPerEth
balances := []uint64{defaultBal, extraBal, extraBal + params.BeaconConfig().GweiPerEth}
require.NoError(t, headState.SetBalances(balances))
publicKey1 := bytesutil.ToBytes48([]byte{1})
publicKey2 := bytesutil.ToBytes48([]byte{2})
publicKey3 := bytesutil.ToBytes48([]byte{3})
validators := []*ethpb.Validator{
{
PublicKey: publicKey1[:],
ActivationEpoch: 5,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
},
{
PublicKey: publicKey2[:],
EffectiveBalance: defaultBal,
ActivationEpoch: 0,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
},
{
PublicKey: publicKey3[:],
EffectiveBalance: defaultBal,
ActivationEpoch: 0,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
},
}
require.NoError(t, headState.SetValidators(validators))
require.NoError(t, headState.SetInactivityScores([]uint64{0, 0, 0}))
require.NoError(t, headState.SetBalances([]uint64{100, 101, 102}))
offset := int64(headState.Slot().Mul(params.BeaconConfig().SecondsPerSlot))
bs := &Server{
HeadFetcher: &mock.ChainService{
State: headState,
},
GenesisTimeFetcher: &mock.ChainService{Genesis: time.Now().Add(time.Duration(-1*offset) * time.Second)},
SyncChecker: &mockSync.Sync{IsSyncing: false},
}
want := &ethpb.ValidatorPerformanceResponse{
PublicKeys: [][]byte{publicKey2[:], publicKey3[:]},
CurrentEffectiveBalances: []uint64{params.BeaconConfig().MaxEffectiveBalance, params.BeaconConfig().MaxEffectiveBalance},
CorrectlyVotedSource: []bool{false, false},
CorrectlyVotedTarget: []bool{false, false},
CorrectlyVotedHead: []bool{false, false},
BalancesBeforeEpochTransition: []uint64{101, 102},
BalancesAfterEpochTransition: []uint64{0, 0},
MissingValidators: [][]byte{publicKey1[:]},
InactivityScores: []uint64{0, 0},
}

res, err := bs.GetValidatorPerformance(ctx, &ethpb.ValidatorPerformanceRequest{
PublicKeys: [][]byte{publicKey1[:], publicKey3[:], publicKey2[:]},
})
require.NoError(t, err)
if !proto.Equal(want, res) {
t.Errorf("Wanted %v\nReceived %v", want, res)
}
}

func BenchmarkListValidatorBalances(b *testing.B) {
b.StopTimer()
beaconDB := dbTest.SetupDB(b)
Expand Down Expand Up @@ -2592,6 +2678,94 @@ func TestServer_GetIndividualVotes_BellatrixEndOfEpoch(t *testing.T) {
assert.DeepEqual(t, wanted, res, "Unexpected response")
}

func TestServer_GetIndividualVotes_CapellaEndOfEpoch(t *testing.T) {
helpers.ClearCache()
params.SetupTestConfigCleanup(t)
params.OverrideBeaconConfig(params.BeaconConfig())
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()

validators := uint64(32)
beaconState, _ := util.DeterministicGenesisStateCapella(t, validators)
startSlot, err := slots.EpochStart(1)
assert.NoError(t, err)
require.NoError(t, beaconState.SetSlot(startSlot))

b := util.NewBeaconBlock()
b.Block.Slot = startSlot
util.SaveBlock(t, ctx, beaconDB, b)
gRoot, err := b.Block.HashTreeRoot()
require.NoError(t, err)
gen := stategen.New(beaconDB, doublylinkedtree.New())
require.NoError(t, gen.SaveState(ctx, gRoot, beaconState))
require.NoError(t, beaconDB.SaveState(ctx, beaconState, gRoot))
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
// Save State at the end of the epoch:
endSlot, err := slots.EpochEnd(1)
assert.NoError(t, err)

beaconState, _ = util.DeterministicGenesisStateCapella(t, validators)
require.NoError(t, beaconState.SetSlot(endSlot))

pb, err := beaconState.CurrentEpochParticipation()
require.NoError(t, err)
for i := range pb {
pb[i] = 0xff
}
require.NoError(t, beaconState.SetCurrentParticipationBits(pb))
require.NoError(t, beaconState.SetPreviousParticipationBits(pb))

b.Block.Slot = endSlot
util.SaveBlock(t, ctx, beaconDB, b)
gRoot, err = b.Block.HashTreeRoot()
require.NoError(t, err)

require.NoError(t, gen.SaveState(ctx, gRoot, beaconState))
require.NoError(t, beaconDB.SaveState(ctx, beaconState, gRoot))
bs := &Server{
StateGen: gen,
GenesisTimeFetcher: &mock.ChainService{},
}
addDefaultReplayerBuilder(bs, beaconDB)

res, err := bs.GetIndividualVotes(ctx, &ethpb.IndividualVotesRequest{
Indices: []types.ValidatorIndex{0, 1},
Epoch: 1,
})
require.NoError(t, err)
wanted := &ethpb.IndividualVotesRespond{
IndividualVotes: []*ethpb.IndividualVotesRespond_IndividualVote{
{
ValidatorIndex: 0,
PublicKey: beaconState.Validators()[0].PublicKey,
IsActiveInCurrentEpoch: true,
IsActiveInPreviousEpoch: true,
IsCurrentEpochTargetAttester: true,
IsCurrentEpochAttester: true,
IsPreviousEpochAttester: true,
IsPreviousEpochHeadAttester: true,
IsPreviousEpochTargetAttester: true,
CurrentEpochEffectiveBalanceGwei: params.BeaconConfig().MaxEffectiveBalance,
Epoch: 1,
},
{
ValidatorIndex: 1,
PublicKey: beaconState.Validators()[1].PublicKey,
IsActiveInCurrentEpoch: true,
IsActiveInPreviousEpoch: true,
IsCurrentEpochTargetAttester: true,
IsCurrentEpochAttester: true,
IsPreviousEpochAttester: true,
IsPreviousEpochHeadAttester: true,
IsPreviousEpochTargetAttester: true,
CurrentEpochEffectiveBalanceGwei: params.BeaconConfig().MaxEffectiveBalance,
Epoch: 1,
},
},
}
assert.DeepEqual(t, wanted, res, "Unexpected response")
}

func Test_validatorStatus(t *testing.T) {
tests := []struct {
name string
Expand Down