From 40b6ee4e39ccb1def4cd43d3e567ecb025dbffff Mon Sep 17 00:00:00 2001 From: terence tsao Date: Wed, 15 Apr 2020 20:15:59 -0700 Subject: [PATCH 1/9] Fix ListValidatorBalances --- beacon-chain/rpc/beacon/validators.go | 64 +++++++++------------------ 1 file changed, 22 insertions(+), 42 deletions(-) diff --git a/beacon-chain/rpc/beacon/validators.go b/beacon-chain/rpc/beacon/validators.go index 1c28f2b933ed..c79bdae1e5eb 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: currentEpoch, 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, From a4902e4c3d510fb92fc1971952487e72d30adfe1 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Wed, 15 Apr 2020 21:27:53 -0700 Subject: [PATCH 2/9] Fixed all the tests --- beacon-chain/rpc/beacon/validators_test.go | 339 ++++++--------------- 1 file changed, 98 insertions(+), 241 deletions(-) diff --git a/beacon-chain/rpc/beacon/validators_test.go b/beacon-chain/rpc/beacon/validators_test.go index 0fd3834439b8..be843553b127 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,15 +75,31 @@ 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), NextPageToken: strconv.Itoa(0), + Epoch: helpers.SlotToEpoch(bs.GenesisTimeFetcher.CurrentSlot()), } res, err := bs.ListValidatorBalances( ctx, @@ -131,84 +148,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 +183,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 +222,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 +237,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 +273,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 +284,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 +294,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 +304,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 +328,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 +364,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 +374,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 +383,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 +405,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 +1517,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) From 8b4e3e74db5bdd327eb398d58ebb7890fa939487 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Thu, 16 Apr 2020 08:41:36 -0700 Subject: [PATCH 3/9] Use requestedEpoch as default --- beacon-chain/rpc/beacon/validators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon-chain/rpc/beacon/validators.go b/beacon-chain/rpc/beacon/validators.go index c79bdae1e5eb..2ae9ac852a1e 100644 --- a/beacon-chain/rpc/beacon/validators.go +++ b/beacon-chain/rpc/beacon/validators.go @@ -110,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: currentEpoch, + Epoch: requestedEpoch, Balances: make([]*ethpb.ValidatorBalances_Balance, 0), TotalSize: int32(0), NextPageToken: strconv.Itoa(0), From 81fa1b8ea07ee805dc6d31c0169d1e1b39cc0e4b Mon Sep 17 00:00:00 2001 From: terence tsao Date: Thu, 16 Apr 2020 08:57:44 -0700 Subject: [PATCH 4/9] Fixed a test --- beacon-chain/rpc/beacon/validators_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/beacon-chain/rpc/beacon/validators_test.go b/beacon-chain/rpc/beacon/validators_test.go index be843553b127..e9697a76c03f 100644 --- a/beacon-chain/rpc/beacon/validators_test.go +++ b/beacon-chain/rpc/beacon/validators_test.go @@ -99,7 +99,6 @@ func TestServer_ListValidatorBalances_NoResults(t *testing.T) { Balances: make([]*ethpb.ValidatorBalances_Balance, 0), TotalSize: int32(0), NextPageToken: strconv.Itoa(0), - Epoch: helpers.SlotToEpoch(bs.GenesisTimeFetcher.CurrentSlot()), } res, err := bs.ListValidatorBalances( ctx, From 8fc74c8fb5bd4cd9a063afaeddbb9117c7a43768 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Sat, 25 Apr 2020 09:59:56 -0700 Subject: [PATCH 5/9] Add fallback --- beacon-chain/rpc/beacon/validators.go | 149 ++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/beacon-chain/rpc/beacon/validators.go b/beacon-chain/rpc/beacon/validators.go index 99b5fe00bd77..82d71c84f2a7 100644 --- a/beacon-chain/rpc/beacon/validators.go +++ b/beacon-chain/rpc/beacon/validators.go @@ -31,6 +31,10 @@ func (bs *Server) ListValidatorBalances( req.PageSize, flags.Get().MaxPageSize) } + if !featureconfig.Get().NewStateMgmt { + return bs.listValidatorsBalancesUsingOldArchival(ctx, req) + } + currentEpoch := helpers.SlotToEpoch(bs.GenesisTimeFetcher.CurrentSlot()) requestedEpoch := currentEpoch switch q := req.QueryFilter.(type) { @@ -153,6 +157,151 @@ func (bs *Server) ListValidatorBalances( }, nil } +func (bs *Server) listValidatorsBalancesUsingOldArchival( + ctx context.Context, + req *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) { + 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 + switch q := req.QueryFilter.(type) { + case *ethpb.ListValidatorBalancesRequest_Epoch: + epoch = q.Epoch + case *ethpb.ListValidatorBalancesRequest_Genesis: + requestingGenesis = q.Genesis + default: + epoch = helpers.CurrentEpoch(headState) + } + + 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. + return nil, status.Errorf( + codes.InvalidArgument, + "Cannot retrieve information about an epoch in the future, current epoch %d, requesting %d", + helpers.CurrentEpoch(headState), + epoch, + ) + } + + balancesCount := len(balances) + for _, pubKey := range req.PublicKeys { + // Skip empty public key. + if len(pubKey) == 0 { + continue + } + pubkeyBytes := bytesutil.ToBytes48(pubKey) + index, ok := headState.ValidatorIndexByPubkey(pubkeyBytes) + if !ok { + return nil, status.Errorf(codes.NotFound, "Could not find validator index for public key %#x", pubkeyBytes) + } + + filtered[index] = true + + if int(index) >= len(balances) { + return nil, status.Errorf(codes.OutOfRange, "Validator index %d >= balance list %d", + index, len(balances)) + } + + res = append(res, ðpb.ValidatorBalances_Balance{ + PublicKey: pubKey, + Index: index, + Balance: balances[index], + }) + balancesCount = len(res) + } + + 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)) + } + + if !filtered[index] { + res = append(res, ðpb.ValidatorBalances_Balance{ + PublicKey: validators[index].PublicKey, + Index: index, + Balance: balances[index], + }) + } + balancesCount = len(res) + } + // Depending on the indices and public keys given, results might not be sorted. + sort.Slice(res, func(i, j int) bool { + return res[i].Index < res[j].Index + }) + + // If there are no balances, we simply return a response specifying this. + // Otherwise, attempting to paginate 0 balances below would result in an error. + if balancesCount == 0 { + return ðpb.ValidatorBalances{ + Epoch: epoch, + Balances: make([]*ethpb.ValidatorBalances_Balance, 0), + TotalSize: int32(0), + NextPageToken: strconv.Itoa(0), + }, nil + } + + start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), balancesCount) + if err != nil { + return nil, status.Errorf( + codes.Internal, + "Could not paginate results: %v", + err, + ) + } + + if len(req.Indices) == 0 && len(req.PublicKeys) == 0 { + // Return everything. + for i := start; i < end; i++ { + pubkey := headState.PubkeyAtIndex(uint64(i)) + res = append(res, ðpb.ValidatorBalances_Balance{ + PublicKey: pubkey[:], + Index: uint64(i), + Balance: balances[i], + }) + } + return ðpb.ValidatorBalances{ + Epoch: epoch, + Balances: res, + TotalSize: int32(balancesCount), + NextPageToken: nextPageToken, + }, nil + } + + return ðpb.ValidatorBalances{ + Epoch: epoch, + Balances: res[start:end], + TotalSize: int32(balancesCount), + NextPageToken: nextPageToken, + }, nil +} + // ListValidators retrieves the current list of active validators with an optional historical epoch flag to // to retrieve validator set in time. func (bs *Server) ListValidators( From af46edcbf9d2224e82a96c30b627f7182f2a9f9c Mon Sep 17 00:00:00 2001 From: terence tsao Date: Sat, 25 Apr 2020 10:07:38 -0700 Subject: [PATCH 6/9] Fixed test --- beacon-chain/rpc/beacon/validators_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/beacon-chain/rpc/beacon/validators_test.go b/beacon-chain/rpc/beacon/validators_test.go index 1a3f6a85f4da..f797cde6c448 100644 --- a/beacon-chain/rpc/beacon/validators_test.go +++ b/beacon-chain/rpc/beacon/validators_test.go @@ -91,6 +91,11 @@ func TestServer_ListValidatorBalances_NoResults(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) + config := &featureconfig.Flags{ + NewStateMgmt: true, + } + featureconfig.Init(config) + ctx := context.Background() st := testutil.NewBeaconState() if err := st.SetSlot(0); err != nil { @@ -1506,6 +1511,11 @@ func TestServer_GetValidatorParticipation_CannotRequestFutureEpoch(t *testing.T) db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) + config := &featureconfig.Flags{ + NewStateMgmt: false, + } + featureconfig.Init(config) + ctx := context.Background() headState := testutil.NewBeaconState() if err := headState.SetSlot(0); err != nil { @@ -1536,6 +1546,12 @@ func TestServer_GetValidatorParticipation_FromArchive(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) ctx := context.Background() + + config := &featureconfig.Flags{ + NewStateMgmt: false, + } + featureconfig.Init(config) + epoch := uint64(4) part := ðpb.ValidatorParticipation{ GlobalParticipationRate: 1.0, @@ -1702,6 +1718,12 @@ func TestServer_GetValidatorParticipation_FromArchive_FinalizedEpoch(t *testing. db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) ctx := context.Background() + + config := &featureconfig.Flags{ + NewStateMgmt: false, + } + featureconfig.Init(config) + part := ðpb.ValidatorParticipation{ GlobalParticipationRate: 1.0, VotedEther: 20, From b1d5088eb52a2e8a530cbeb3f9890c6a8e4362ff Mon Sep 17 00:00:00 2001 From: terence tsao Date: Sat, 25 Apr 2020 10:21:15 -0700 Subject: [PATCH 7/9] Fixed a few more tests --- beacon-chain/rpc/beacon/attestations_test.go | 6 + beacon-chain/rpc/beacon/validators_test.go | 114 +++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/beacon-chain/rpc/beacon/attestations_test.go b/beacon-chain/rpc/beacon/attestations_test.go index cc1f825984dc..d5c631cc9138 100644 --- a/beacon-chain/rpc/beacon/attestations_test.go +++ b/beacon-chain/rpc/beacon/attestations_test.go @@ -612,6 +612,12 @@ func TestServer_ListIndexedAttestations_NewStateManagnmentDisabled(t *testing.T) func TestServer_ListIndexedAttestations_GenesisEpoch(t *testing.T) { params.OverrideBeaconConfig(params.MainnetConfig()) defer params.OverrideBeaconConfig(params.MinimalSpecConfig()) + + config := &featureconfig.Flags{ + NewStateMgmt: true, + } + featureconfig.Init(config) + cfg := assertNewStateMgmtIsEnabled() defer featureconfig.Init(cfg) db := dbTest.SetupDB(t) diff --git a/beacon-chain/rpc/beacon/validators_test.go b/beacon-chain/rpc/beacon/validators_test.go index f797cde6c448..4568031c21dd 100644 --- a/beacon-chain/rpc/beacon/validators_test.go +++ b/beacon-chain/rpc/beacon/validators_test.go @@ -491,10 +491,119 @@ func TestServer_ListValidators_CannotRequestFutureEpoch(t *testing.T) { } } +func TestServer_ListValidatorBalances_FromArchive(t *testing.T) { + db := dbTest.SetupDB(t) + defer dbTest.TeardownDB(t, db) + ctx := context.Background() + + config := &featureconfig.Flags{ + NewStateMgmt: false, + } + featureconfig.Init(config) + + 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) + 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() + + config := &featureconfig.Flags{ + NewStateMgmt: false, + } + featureconfig.Init(config) + + 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 { + t.Fatal(err) + } + if err := st.SetBalances(newBalances); 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{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) + } +} + func TestServer_ListValidators_NoResults(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) + config := &featureconfig.Flags{ + NewStateMgmt: true, + } + featureconfig.Init(config) + ctx := context.Background() st := testutil.NewBeaconState() if err := st.SetSlot(0); err != nil { @@ -1061,6 +1170,11 @@ func TestServer_GetValidatorActiveSetChanges(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) + config := &featureconfig.Flags{ + NewStateMgmt: true, + } + featureconfig.Init(config) + ctx := context.Background() validators := make([]*ethpb.Validator, 8) headState := testutil.NewBeaconState() From 85886a82e3c237465b1cf67a6005be95c79038d6 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Sat, 25 Apr 2020 10:22:08 -0700 Subject: [PATCH 8/9] Addback benchmark --- beacon-chain/rpc/beacon/validators_test.go | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/beacon-chain/rpc/beacon/validators_test.go b/beacon-chain/rpc/beacon/validators_test.go index 4568031c21dd..f69737e503c7 100644 --- a/beacon-chain/rpc/beacon/validators_test.go +++ b/beacon-chain/rpc/beacon/validators_test.go @@ -1911,6 +1911,58 @@ 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) From cc082142ba1ff1814e992d2b92e55d617eb64adc Mon Sep 17 00:00:00 2001 From: terence tsao Date: Sun, 26 Apr 2020 17:21:26 -0700 Subject: [PATCH 9/9] Victor's feedback --- beacon-chain/rpc/beacon/attestations_test.go | 6 ++--- beacon-chain/rpc/beacon/validators_test.go | 23 ++++++++++---------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/beacon-chain/rpc/beacon/attestations_test.go b/beacon-chain/rpc/beacon/attestations_test.go index d5c631cc9138..9b5f9aea52ce 100644 --- a/beacon-chain/rpc/beacon/attestations_test.go +++ b/beacon-chain/rpc/beacon/attestations_test.go @@ -613,10 +613,8 @@ func TestServer_ListIndexedAttestations_GenesisEpoch(t *testing.T) { params.OverrideBeaconConfig(params.MainnetConfig()) defer params.OverrideBeaconConfig(params.MinimalSpecConfig()) - config := &featureconfig.Flags{ - NewStateMgmt: true, - } - featureconfig.Init(config) + featureconfig.Init(&featureconfig.Flags{NewStateMgmt: true}) + defer featureconfig.Init(&featureconfig.Flags{NewStateMgmt: false}) cfg := assertNewStateMgmtIsEnabled() defer featureconfig.Init(cfg) diff --git a/beacon-chain/rpc/beacon/validators_test.go b/beacon-chain/rpc/beacon/validators_test.go index f69737e503c7..de9ada680637 100644 --- a/beacon-chain/rpc/beacon/validators_test.go +++ b/beacon-chain/rpc/beacon/validators_test.go @@ -91,10 +91,8 @@ func TestServer_ListValidatorBalances_NoResults(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) - config := &featureconfig.Flags{ - NewStateMgmt: true, - } - featureconfig.Init(config) + featureconfig.Init(&featureconfig.Flags{NewStateMgmt: true}) + defer featureconfig.Init(&featureconfig.Flags{NewStateMgmt: false}) ctx := context.Background() st := testutil.NewBeaconState() @@ -263,7 +261,10 @@ func pubKey(i uint64) []byte { func TestServer_ListValidatorBalances_Pagination_Default(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) + featureconfig.Init(&featureconfig.Flags{NewStateMgmt: true}) + defer featureconfig.Init(&featureconfig.Flags{NewStateMgmt: false}) ctx := context.Background() + setupValidators(t, db, 100) headState, err := db.HeadState(context.Background()) if err != nil { @@ -599,10 +600,8 @@ func TestServer_ListValidators_NoResults(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) - config := &featureconfig.Flags{ - NewStateMgmt: true, - } - featureconfig.Init(config) + featureconfig.Init(&featureconfig.Flags{NewStateMgmt: true}) + defer featureconfig.Init(&featureconfig.Flags{NewStateMgmt: false}) ctx := context.Background() st := testutil.NewBeaconState() @@ -1170,10 +1169,8 @@ func TestServer_GetValidatorActiveSetChanges(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) - config := &featureconfig.Flags{ - NewStateMgmt: true, - } - featureconfig.Init(config) + featureconfig.Init(&featureconfig.Flags{NewStateMgmt: true}) + defer featureconfig.Init(&featureconfig.Flags{NewStateMgmt: false}) ctx := context.Background() validators := make([]*ethpb.Validator, 8) @@ -1726,6 +1723,8 @@ func TestServer_GetValidatorParticipation_FromArchive(t *testing.T) { func TestServer_GetValidatorParticipation_PrevEpoch(t *testing.T) { db := dbTest.SetupDB(t) defer dbTest.TeardownDB(t, db) + featureconfig.Init(&featureconfig.Flags{NewStateMgmt: true}) + defer featureconfig.Init(&featureconfig.Flags{NewStateMgmt: false}) ctx := context.Background() validatorCount := uint64(100)