diff --git a/beacon-chain/rpc/beacon/validators.go b/beacon-chain/rpc/beacon/validators.go index 1c28f2b933e..2ae9ac852a1 100644 --- a/beacon-chain/rpc/beacon/validators.go +++ b/beacon-chain/rpc/beacon/validators.go @@ -30,51 +30,35 @@ func (bs *Server) ListValidatorBalances( req.PageSize, flags.Get().MaxPageSize) } - res := make([]*ethpb.ValidatorBalances_Balance, 0) - filtered := map[uint64]bool{} // Track filtered validators to prevent duplication in the response. - - headState, err := bs.HeadFetcher.HeadState(ctx) - if err != nil { - return nil, status.Error(codes.Internal, "Could not get head state") - } - - var requestingGenesis bool - var epoch uint64 + currentEpoch := helpers.SlotToEpoch(bs.GenesisTimeFetcher.CurrentSlot()) + requestedEpoch := currentEpoch switch q := req.QueryFilter.(type) { case *ethpb.ListValidatorBalancesRequest_Epoch: - epoch = q.Epoch + requestedEpoch = q.Epoch case *ethpb.ListValidatorBalancesRequest_Genesis: - requestingGenesis = q.Genesis + requestedEpoch = 0 default: - epoch = helpers.CurrentEpoch(headState) + requestedEpoch = currentEpoch } - var balances []uint64 - validators := headState.Validators() - if requestingGenesis || epoch < helpers.CurrentEpoch(headState) { - balances, err = bs.BeaconDB.ArchivedBalances(ctx, epoch) - if err != nil { - return nil, status.Errorf(codes.Internal, "Could not retrieve balances for epoch %d", epoch) - } - if balances == nil { - return nil, status.Errorf( - codes.NotFound, - "Could not retrieve data for epoch %d, perhaps --archive in the running beacon node is disabled", - 0, - ) - } - } else if epoch == helpers.CurrentEpoch(headState) { - balances = headState.Balances() - } else { - // Otherwise, we are requesting data from the future and we return an error. + if requestedEpoch > currentEpoch { return nil, status.Errorf( codes.InvalidArgument, "Cannot retrieve information about an epoch in the future, current epoch %d, requesting %d", - helpers.CurrentEpoch(headState), - epoch, + currentEpoch, + requestedEpoch, ) } + res := make([]*ethpb.ValidatorBalances_Balance, 0) + filtered := map[uint64]bool{} // Track filtered validators to prevent duplication in the response. + requestedState, err := bs.StateGen.StateBySlot(ctx, helpers.StartSlot(requestedEpoch)) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not get state") + } + + validators := requestedState.Validators() + balances := requestedState.Balances() balancesCount := len(balances) for _, pubKey := range req.PublicKeys { // Skip empty public key. @@ -82,7 +66,7 @@ func (bs *Server) ListValidatorBalances( continue } pubkeyBytes := bytesutil.ToBytes48(pubKey) - index, ok := headState.ValidatorIndexByPubkey(pubkeyBytes) + index, ok := requestedState.ValidatorIndexByPubkey(pubkeyBytes) if !ok { return nil, status.Errorf(codes.NotFound, "Could not find validator index for public key %#x", pubkeyBytes) } @@ -104,10 +88,6 @@ func (bs *Server) ListValidatorBalances( for _, index := range req.Indices { if int(index) >= len(balances) { - if epoch <= helpers.CurrentEpoch(headState) { - return nil, status.Errorf(codes.OutOfRange, "Validator index %d does not exist in historical balances", - index) - } return nil, status.Errorf(codes.OutOfRange, "Validator index %d >= balance list %d", index, len(balances)) } @@ -130,7 +110,7 @@ func (bs *Server) ListValidatorBalances( // Otherwise, attempting to paginate 0 balances below would result in an error. if balancesCount == 0 { return ðpb.ValidatorBalances{ - Epoch: epoch, + Epoch: requestedEpoch, Balances: make([]*ethpb.ValidatorBalances_Balance, 0), TotalSize: int32(0), NextPageToken: strconv.Itoa(0), @@ -149,7 +129,7 @@ func (bs *Server) ListValidatorBalances( if len(req.Indices) == 0 && len(req.PublicKeys) == 0 { // Return everything. for i := start; i < end; i++ { - pubkey := headState.PubkeyAtIndex(uint64(i)) + pubkey := requestedState.PubkeyAtIndex(uint64(i)) res = append(res, ðpb.ValidatorBalances_Balance{ PublicKey: pubkey[:], Index: uint64(i), @@ -157,7 +137,7 @@ func (bs *Server) ListValidatorBalances( }) } return ðpb.ValidatorBalances{ - Epoch: epoch, + Epoch: requestedEpoch, Balances: res, TotalSize: int32(balancesCount), NextPageToken: nextPageToken, @@ -165,7 +145,7 @@ func (bs *Server) ListValidatorBalances( } return ðpb.ValidatorBalances{ - Epoch: epoch, + Epoch: requestedEpoch, Balances: res[start:end], TotalSize: int32(balancesCount), NextPageToken: nextPageToken, diff --git a/beacon-chain/rpc/beacon/validators_test.go b/beacon-chain/rpc/beacon/validators_test.go index 0fd3834439b..e9697a76c03 100644 --- a/beacon-chain/rpc/beacon/validators_test.go +++ b/beacon-chain/rpc/beacon/validators_test.go @@ -49,6 +49,7 @@ func TestServer_ListValidatorBalances_CannotRequestFutureEpoch(t *testing.T) { HeadFetcher: &mock.ChainService{ State: st, }, + GenesisTimeFetcher: &mock.ChainService{}, } wanted := "Cannot retrieve information about an epoch in the future" @@ -56,7 +57,7 @@ func TestServer_ListValidatorBalances_CannotRequestFutureEpoch(t *testing.T) { ctx, ðpb.ListValidatorBalancesRequest{ QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{ - Epoch: 1, + Epoch: helpers.SlotToEpoch(bs.GenesisTimeFetcher.CurrentSlot()) + 1, }, }, ); err != nil && !strings.Contains(err.Error(), wanted) { @@ -74,11 +75,26 @@ func TestServer_ListValidatorBalances_NoResults(t *testing.T) { t.Fatal(err) } bs := &Server{ - BeaconDB: db, - HeadFetcher: &mock.ChainService{ - State: st, - }, + GenesisTimeFetcher: &mock.ChainService{}, + StateGen: stategen.New(db, cache.NewStateSummaryCache()), + } + + headState := testutil.NewBeaconState() + b := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{}} + if err := db.SaveBlock(ctx, b); err != nil { + t.Fatal(err) } + gRoot, err := ssz.HashTreeRoot(b.Block) + if err != nil { + t.Fatal(err) + } + if err := db.SaveGenesisBlockRoot(ctx, gRoot); err != nil { + t.Fatal(err) + } + if err := db.SaveState(ctx, headState, gRoot); err != nil { + t.Fatal(err) + } + wanted := ðpb.ValidatorBalances{ Balances: make([]*ethpb.ValidatorBalances_Balance, 0), TotalSize: int32(0), @@ -131,84 +147,28 @@ func TestServer_ListValidatorBalances_DefaultResponse_NoArchive(t *testing.T) { if err := st.SetBalances(balances); err != nil { t.Fatal(err) } - bs := &Server{ - BeaconDB: db, - HeadFetcher: &mock.ChainService{ - State: st, - }, - } - res, err := bs.ListValidatorBalances( - ctx, - ðpb.ListValidatorBalancesRequest{ - QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{ - Epoch: 0, - }, - }, - ) - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(balancesResponse, res.Balances) { - t.Errorf("Wanted %v, received %v", balancesResponse, res.Balances) - } -} - -func TestServer_ListValidatorBalances_DefaultResponse_FromArchive(t *testing.T) { - db := dbTest.SetupDB(t) - defer dbTest.TeardownDB(t, db) - - ctx := context.Background() - currentNumValidators := 100 - numOldBalances := 50 - validators := make([]*ethpb.Validator, currentNumValidators) - balances := make([]uint64, currentNumValidators) - oldBalances := make([]uint64, numOldBalances) - balancesResponse := make([]*ethpb.ValidatorBalances_Balance, numOldBalances) - for i := 0; i < currentNumValidators; i++ { - key := make([]byte, 48) - copy(key, strconv.Itoa(i)) - validators[i] = ðpb.Validator{ - PublicKey: key, - WithdrawalCredentials: make([]byte, 32), - } - balances[i] = params.BeaconConfig().MaxEffectiveBalance - } - for i := 0; i < numOldBalances; i++ { - oldBalances[i] = params.BeaconConfig().MaxEffectiveBalance - key := make([]byte, 48) - copy(key, strconv.Itoa(i)) - balancesResponse[i] = ðpb.ValidatorBalances_Balance{ - PublicKey: key, - Index: uint64(i), - Balance: params.BeaconConfig().MaxEffectiveBalance, - } - } - // We archive old balances for epoch 50. - if err := db.SaveArchivedBalances(ctx, 50, oldBalances); err != nil { + b := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{}} + if err := db.SaveBlock(ctx, b); err != nil { t.Fatal(err) } - st := testutil.NewBeaconState() - if err := st.SetSlot(helpers.StartSlot(100) /* epoch 100 */); err != nil { + gRoot, err := ssz.HashTreeRoot(b.Block) + if err != nil { t.Fatal(err) } - if err := st.SetValidators(validators); err != nil { + if err := db.SaveGenesisBlockRoot(ctx, gRoot); err != nil { t.Fatal(err) } - if err := st.SetBalances(balances); err != nil { + if err := db.SaveState(ctx, st, gRoot); err != nil { t.Fatal(err) } bs := &Server{ - BeaconDB: db, - HeadFetcher: &mock.ChainService{ - State: st, - }, + GenesisTimeFetcher: &mock.ChainService{}, + StateGen: stategen.New(db, cache.NewStateSummaryCache()), } res, err := bs.ListValidatorBalances( ctx, ðpb.ListValidatorBalancesRequest{ - QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{ - Epoch: 50, - }, + QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}, }, ) if err != nil { @@ -222,22 +182,31 @@ func TestServer_ListValidatorBalances_DefaultResponse_FromArchive(t *testing.T) func TestServer_ListValidatorBalances_PaginationOutOfRange(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) - + ctx := context.Background() setupValidators(t, db, 3) - - headState, err := db.HeadState(context.Background()) + st := testutil.NewBeaconState() + b := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{}} + if err := db.SaveBlock(ctx, b); err != nil { + t.Fatal(err) + } + gRoot, err := ssz.HashTreeRoot(b.Block) if err != nil { t.Fatal(err) } + if err := db.SaveGenesisBlockRoot(ctx, gRoot); err != nil { + t.Fatal(err) + } + if err := db.SaveState(ctx, st, gRoot); err != nil { + t.Fatal(err) + } bs := &Server{ - HeadFetcher: &mock.ChainService{ - State: headState, - }, + GenesisTimeFetcher: &mock.ChainService{}, + StateGen: stategen.New(db, cache.NewStateSummaryCache()), } - req := ðpb.ListValidatorBalancesRequest{PageToken: strconv.Itoa(1), PageSize: 100} - wanted := fmt.Sprintf("page start %d >= list %d", req.PageSize, len(headState.Balances())) + req := ðpb.ListValidatorBalancesRequest{PageToken: strconv.Itoa(1), PageSize: 100, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}} + wanted := fmt.Sprintf("page start %d >= list %d", req.PageSize, len(st.Balances())) if _, err := bs.ListValidatorBalances(context.Background(), req); err != nil && !strings.Contains(err.Error(), wanted) { t.Errorf("Expected error %v, received %v", wanted, err) } @@ -252,7 +221,7 @@ func TestServer_ListValidatorBalances_ExceedsMaxPageSize(t *testing.T) { exceedsMax, flags.Get().MaxPageSize, ) - req := ðpb.ListValidatorBalancesRequest{PageToken: strconv.Itoa(0), PageSize: exceedsMax} + req := ðpb.ListValidatorBalancesRequest{PageSize: exceedsMax} if _, err := bs.ListValidatorBalances(context.Background(), req); err != nil && !strings.Contains(err.Error(), wanted) { t.Errorf("Expected error %v, received %v", wanted, err) } @@ -267,24 +236,34 @@ func pubKey(i uint64) []byte { func TestServer_ListValidatorBalances_Pagination_Default(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) - + ctx := context.Background() setupValidators(t, db, 100) - headState, err := db.HeadState(context.Background()) if err != nil { t.Fatal(err) } + b := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{}} + gRoot, err := ssz.HashTreeRoot(b.Block) + if err != nil { + t.Fatal(err) + } + if err := db.SaveGenesisBlockRoot(ctx, gRoot); err != nil { + t.Fatal(err) + } + if err := db.SaveState(ctx, headState, gRoot); err != nil { + t.Fatal(err) + } bs := &Server{ - BeaconDB: db, - HeadFetcher: &mock.ChainService{State: headState}, + GenesisTimeFetcher: &mock.ChainService{}, + StateGen: stategen.New(db, cache.NewStateSummaryCache()), } tests := []struct { req *ethpb.ListValidatorBalancesRequest res *ethpb.ValidatorBalances }{ - {req: ðpb.ListValidatorBalancesRequest{PublicKeys: [][]byte{pubKey(99)}}, + {req: ðpb.ListValidatorBalancesRequest{PublicKeys: [][]byte{pubKey(99)}, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}}, res: ðpb.ValidatorBalances{ Balances: []*ethpb.ValidatorBalances_Balance{ {Index: 99, PublicKey: pubKey(99), Balance: 99}, @@ -293,7 +272,7 @@ func TestServer_ListValidatorBalances_Pagination_Default(t *testing.T) { TotalSize: 1, }, }, - {req: ðpb.ListValidatorBalancesRequest{Indices: []uint64{1, 2, 3}}, + {req: ðpb.ListValidatorBalancesRequest{Indices: []uint64{1, 2, 3}, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}}, res: ðpb.ValidatorBalances{ Balances: []*ethpb.ValidatorBalances_Balance{ {Index: 1, PublicKey: pubKey(1), Balance: 1}, @@ -304,7 +283,7 @@ func TestServer_ListValidatorBalances_Pagination_Default(t *testing.T) { TotalSize: 3, }, }, - {req: ðpb.ListValidatorBalancesRequest{PublicKeys: [][]byte{pubKey(10), pubKey(11), pubKey(12)}}, + {req: ðpb.ListValidatorBalancesRequest{PublicKeys: [][]byte{pubKey(10), pubKey(11), pubKey(12)}, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}}, res: ðpb.ValidatorBalances{ Balances: []*ethpb.ValidatorBalances_Balance{ {Index: 10, PublicKey: pubKey(10), Balance: 10}, @@ -314,7 +293,7 @@ func TestServer_ListValidatorBalances_Pagination_Default(t *testing.T) { NextPageToken: "", TotalSize: 3, }}, - {req: ðpb.ListValidatorBalancesRequest{PublicKeys: [][]byte{pubKey(2), pubKey(3)}, Indices: []uint64{3, 4}}, // Duplication + {req: ðpb.ListValidatorBalancesRequest{PublicKeys: [][]byte{pubKey(2), pubKey(3)}, Indices: []uint64{3, 4}, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}}, // Duplication res: ðpb.ValidatorBalances{ Balances: []*ethpb.ValidatorBalances_Balance{ {Index: 2, PublicKey: pubKey(2), Balance: 2}, @@ -324,7 +303,7 @@ func TestServer_ListValidatorBalances_Pagination_Default(t *testing.T) { NextPageToken: "", TotalSize: 3, }}, - {req: ðpb.ListValidatorBalancesRequest{PublicKeys: [][]byte{{}}, Indices: []uint64{3, 4}}, // Public key has a blank value + {req: ðpb.ListValidatorBalancesRequest{PublicKeys: [][]byte{{}}, Indices: []uint64{3, 4}, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}}, // Public key has a blank value res: ðpb.ValidatorBalances{ Balances: []*ethpb.ValidatorBalances_Balance{ {Index: 3, PublicKey: pubKey(3), Balance: 3}, @@ -348,26 +327,35 @@ func TestServer_ListValidatorBalances_Pagination_Default(t *testing.T) { func TestServer_ListValidatorBalances_Pagination_CustomPageSizes(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) - + ctx := context.Background() count := 1000 setupValidators(t, db, count) - headState, err := db.HeadState(context.Background()) if err != nil { t.Fatal(err) } + b := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{}} + gRoot, err := ssz.HashTreeRoot(b.Block) + if err != nil { + t.Fatal(err) + } + if err := db.SaveGenesisBlockRoot(ctx, gRoot); err != nil { + t.Fatal(err) + } + if err := db.SaveState(ctx, headState, gRoot); err != nil { + t.Fatal(err) + } bs := &Server{ - HeadFetcher: &mock.ChainService{ - State: headState, - }, + GenesisTimeFetcher: &mock.ChainService{}, + StateGen: stategen.New(db, cache.NewStateSummaryCache()), } tests := []struct { req *ethpb.ListValidatorBalancesRequest res *ethpb.ValidatorBalances }{ - {req: ðpb.ListValidatorBalancesRequest{PageToken: strconv.Itoa(1), PageSize: 3}, + {req: ðpb.ListValidatorBalancesRequest{PageToken: strconv.Itoa(1), PageSize: 3, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}}, res: ðpb.ValidatorBalances{ Balances: []*ethpb.ValidatorBalances_Balance{ {PublicKey: pubKey(3), Index: 3, Balance: uint64(3)}, @@ -375,7 +363,7 @@ func TestServer_ListValidatorBalances_Pagination_CustomPageSizes(t *testing.T) { {PublicKey: pubKey(5), Index: 5, Balance: uint64(5)}}, NextPageToken: strconv.Itoa(2), TotalSize: int32(count)}}, - {req: ðpb.ListValidatorBalancesRequest{PageToken: strconv.Itoa(10), PageSize: 5}, + {req: ðpb.ListValidatorBalancesRequest{PageToken: strconv.Itoa(10), PageSize: 5, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}}, res: ðpb.ValidatorBalances{ Balances: []*ethpb.ValidatorBalances_Balance{ {PublicKey: pubKey(50), Index: 50, Balance: uint64(50)}, @@ -385,7 +373,7 @@ func TestServer_ListValidatorBalances_Pagination_CustomPageSizes(t *testing.T) { {PublicKey: pubKey(54), Index: 54, Balance: uint64(54)}}, NextPageToken: strconv.Itoa(11), TotalSize: int32(count)}}, - {req: ðpb.ListValidatorBalancesRequest{PageToken: strconv.Itoa(33), PageSize: 3}, + {req: ðpb.ListValidatorBalancesRequest{PageToken: strconv.Itoa(33), PageSize: 3, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}}, res: ðpb.ValidatorBalances{ Balances: []*ethpb.ValidatorBalances_Balance{ {PublicKey: pubKey(99), Index: 99, Balance: uint64(99)}, @@ -394,7 +382,7 @@ func TestServer_ListValidatorBalances_Pagination_CustomPageSizes(t *testing.T) { }, NextPageToken: "34", TotalSize: int32(count)}}, - {req: ðpb.ListValidatorBalancesRequest{PageSize: 2}, + {req: ðpb.ListValidatorBalancesRequest{PageSize: 2, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}}, res: ðpb.ValidatorBalances{ Balances: []*ethpb.ValidatorBalances_Balance{ {PublicKey: pubKey(0), Index: 0, Balance: uint64(0)}, @@ -416,114 +404,34 @@ func TestServer_ListValidatorBalances_Pagination_CustomPageSizes(t *testing.T) { func TestServer_ListValidatorBalances_OutOfRange(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) + ctx := context.Background() setupValidators(t, db, 1) headState, err := db.HeadState(context.Background()) if err != nil { t.Fatal(err) } - - bs := &Server{ - BeaconDB: db, - HeadFetcher: &mock.ChainService{State: headState}, - } - - req := ðpb.ListValidatorBalancesRequest{Indices: []uint64{uint64(1)}} - wanted := "does not exist" - if _, err := bs.ListValidatorBalances(context.Background(), req); err == nil || !strings.Contains(err.Error(), wanted) { - t.Errorf("Expected error %v, received %v", wanted, err) - } -} - -func TestServer_ListValidatorBalances_FromArchive(t *testing.T) { - db := dbTest.SetupDB(t) - defer dbTest.TeardownDB(t, db) - ctx := context.Background() - epoch := uint64(0) - validators, balances := setupValidators(t, db, 100) - - if err := db.SaveArchivedBalances(ctx, epoch, balances); err != nil { - t.Fatal(err) - } - - newerBalances := make([]uint64, len(balances)) - for i := 0; i < len(newerBalances); i++ { - newerBalances[i] = balances[i] * 2 - } - st := testutil.NewBeaconState() - if err := st.SetSlot(params.BeaconConfig().SlotsPerEpoch * 3); err != nil { - t.Fatal(err) - } - if err := st.SetValidators(validators); err != nil { - t.Fatal(err) - } - if err := st.SetBalances(newerBalances); err != nil { - t.Fatal(err) - } - bs := &Server{ - BeaconDB: db, - HeadFetcher: &mock.ChainService{ - State: st, - }, - } - - req := ðpb.ListValidatorBalancesRequest{ - QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}, - Indices: []uint64{uint64(1)}, - } - res, err := bs.ListValidatorBalances(context.Background(), req) + b := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{}} + gRoot, err := ssz.HashTreeRoot(b.Block) if err != nil { t.Fatal(err) } - // We should expect a response containing the old balance from epoch 0, - // not the new balance from the current state. - want := []*ethpb.ValidatorBalances_Balance{ - { - PublicKey: validators[1].PublicKey, - Index: 1, - Balance: balances[1], - }, - } - if !reflect.DeepEqual(want, res.Balances) { - t.Errorf("Wanted %v, received %v", want, res.Balances) - } -} - -func TestServer_ListValidatorBalances_FromArchive_NewValidatorNotFound(t *testing.T) { - db := dbTest.SetupDB(t) - defer dbTest.TeardownDB(t, db) - ctx := context.Background() - epoch := uint64(0) - _, balances := setupValidators(t, db, 100) - - if err := db.SaveArchivedBalances(ctx, epoch, balances); err != nil { - t.Fatal(err) - } - - newValidators, newBalances := setupValidators(t, db, 200) - st := testutil.NewBeaconState() - if err := st.SetSlot(params.BeaconConfig().SlotsPerEpoch * 3); err != nil { - t.Fatal(err) - } - if err := st.SetValidators(newValidators); err != nil { + if err := db.SaveGenesisBlockRoot(ctx, gRoot); err != nil { t.Fatal(err) } - if err := st.SetBalances(newBalances); err != nil { + if err := db.SaveState(ctx, headState, gRoot); err != nil { t.Fatal(err) } + bs := &Server{ - BeaconDB: db, - HeadFetcher: &mock.ChainService{ - State: st, - }, + GenesisTimeFetcher: &mock.ChainService{}, + StateGen: stategen.New(db, cache.NewStateSummaryCache()), } - req := ðpb.ListValidatorBalancesRequest{ - QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}, - Indices: []uint64{1, 150, 161}, - } - if _, err := bs.ListValidatorBalances(context.Background(), req); err == nil || !strings.Contains(err.Error(), "does not exist") { - t.Errorf("Wanted out of range error for including newer validators in the arguments, received %v", err) + req := ðpb.ListValidatorBalancesRequest{Indices: []uint64{uint64(1)}, QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{Epoch: 0}} + wanted := "Validator index 1 >= balance list 1" + if _, err := bs.ListValidatorBalances(context.Background(), req); err == nil || !strings.Contains(err.Error(), wanted) { + t.Errorf("Expected error %v, received %v", wanted, err) } } @@ -1608,58 +1516,6 @@ func BenchmarkListValidatorBalances(b *testing.B) { } } -func BenchmarkListValidatorBalances_FromArchive(b *testing.B) { - b.StopTimer() - db := dbTest.SetupDB(b) - defer dbTest.TeardownDB(b, db) - - ctx := context.Background() - currentNumValidators := 1000 - numOldBalances := 50 - validators := make([]*ethpb.Validator, currentNumValidators) - oldBalances := make([]uint64, numOldBalances) - for i := 0; i < currentNumValidators; i++ { - validators[i] = ðpb.Validator{ - PublicKey: []byte(strconv.Itoa(i)), - } - } - for i := 0; i < numOldBalances; i++ { - oldBalances[i] = params.BeaconConfig().MaxEffectiveBalance - } - // We archive old balances for epoch 50. - if err := db.SaveArchivedBalances(ctx, 50, oldBalances); err != nil { - b.Fatal(err) - } - headState := testutil.NewBeaconState() - if err := headState.SetSlot(helpers.StartSlot(100 /* epoch 100 */)); err != nil { - b.Fatal(err) - } - if err := headState.SetValidators(validators); err != nil { - b.Fatal(err) - } - bs := &Server{ - BeaconDB: db, - HeadFetcher: &mock.ChainService{ - State: headState, - }, - } - - b.StartTimer() - for i := 0; i < b.N; i++ { - if _, err := bs.ListValidatorBalances( - ctx, - ðpb.ListValidatorBalancesRequest{ - QueryFilter: ðpb.ListValidatorBalancesRequest_Epoch{ - Epoch: 50, - }, - PageSize: 100, - }, - ); err != nil { - b.Fatal(err) - } - } -} - func setupValidators(t testing.TB, db db.Database, count int) ([]*ethpb.Validator, []uint64) { ctx := context.Background() balances := make([]uint64, count)