From 01b97ffd5eb535b13b0a4de40dbd4d372b39264f Mon Sep 17 00:00:00 2001 From: terence tsao Date: Fri, 26 Jun 2020 12:01:46 -0700 Subject: [PATCH] Fix `ListValidators` retrieval for new state (#6417) * Retrieve the correct state for new state * Test * Gaz * Merge branch 'master' into fix-list-validators * Merge refs/heads/master into fix-list-validators * Merge refs/heads/master into fix-list-validators * Merge refs/heads/master into fix-list-validators * Merge refs/heads/master into fix-list-validators --- beacon-chain/rpc/beacon/BUILD.bazel | 1 + beacon-chain/rpc/beacon/validators.go | 37 ++++++++++++++-------- beacon-chain/rpc/beacon/validators_test.go | 10 +++++- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/beacon-chain/rpc/beacon/BUILD.bazel b/beacon-chain/rpc/beacon/BUILD.bazel index 180a4f329a..818be140a6 100644 --- a/beacon-chain/rpc/beacon/BUILD.bazel +++ b/beacon-chain/rpc/beacon/BUILD.bazel @@ -79,6 +79,7 @@ go_test( shard_count = 4, deps = [ "//beacon-chain/blockchain/testing:go_default_library", + "//beacon-chain/cache:go_default_library", "//beacon-chain/core/epoch/precompute:go_default_library", "//beacon-chain/core/feed:go_default_library", "//beacon-chain/core/feed/block:go_default_library", diff --git a/beacon-chain/rpc/beacon/validators.go b/beacon-chain/rpc/beacon/validators.go index 1942f706fe..6d2727596c 100644 --- a/beacon-chain/rpc/beacon/validators.go +++ b/beacon-chain/rpc/beacon/validators.go @@ -12,6 +12,7 @@ import ( "github.com/prysmaticlabs/prysm/beacon-chain/core/state" "github.com/prysmaticlabs/prysm/beacon-chain/core/validators" "github.com/prysmaticlabs/prysm/beacon-chain/flags" + beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state" "github.com/prysmaticlabs/prysm/shared/bytesutil" "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/pagination" @@ -319,10 +320,6 @@ func (bs *Server) ListValidators( req.PageSize, flags.Get().MaxPageSize) } - headState, err := bs.HeadFetcher.HeadState(ctx) - if err != nil { - return nil, status.Error(codes.Internal, "Could not get head state") - } currentEpoch := helpers.SlotToEpoch(bs.GenesisTimeFetcher.CurrentSlot()) requestedEpoch := currentEpoch @@ -343,9 +340,23 @@ func (bs *Server) ListValidators( requestedEpoch = q.Epoch } - if helpers.StartSlot(requestedEpoch) > headState.Slot() { - headState = headState.Copy() - headState, err = state.ProcessSlots(ctx, headState, helpers.StartSlot(requestedEpoch)) + var reqState *beaconstate.BeaconState + var err error + if featureconfig.Get().NewStateMgmt { + reqState, err = bs.StateGen.StateBySlot(ctx, helpers.StartSlot(requestedEpoch)) + if err != nil { + return nil, status.Error(codes.Internal, "Could not get requested state") + } + } else { + reqState, err = bs.HeadFetcher.HeadState(ctx) + if err != nil { + return nil, status.Error(codes.Internal, "Could not get head state") + } + } + + if helpers.StartSlot(requestedEpoch) > reqState.Slot() { + reqState = reqState.Copy() + reqState, err = state.ProcessSlots(ctx, reqState, helpers.StartSlot(requestedEpoch)) if err != nil { return nil, status.Errorf( codes.Internal, @@ -359,7 +370,7 @@ func (bs *Server) ListValidators( validatorList := make([]*ethpb.Validators_ValidatorContainer, 0) for _, index := range req.Indices { - val, err := headState.ValidatorAtIndex(index) + val, err := reqState.ValidatorAtIndex(index) if err != nil { return nil, status.Error(codes.Internal, "Could not get validator") } @@ -375,11 +386,11 @@ func (bs *Server) ListValidators( continue } pubkeyBytes := bytesutil.ToBytes48(pubKey) - index, ok := headState.ValidatorIndexByPubkey(pubkeyBytes) + index, ok := reqState.ValidatorIndexByPubkey(pubkeyBytes) if !ok { continue } - val, err := headState.ValidatorAtIndex(index) + val, err := reqState.ValidatorAtIndex(index) if err != nil { return nil, status.Error(codes.Internal, "Could not get validator") } @@ -394,8 +405,8 @@ func (bs *Server) ListValidators( }) if len(req.PublicKeys) == 0 && len(req.Indices) == 0 { - for i := 0; i < headState.NumValidators(); i++ { - val, err := headState.ValidatorAtIndex(uint64(i)) + for i := 0; i < reqState.NumValidators(); i++ { + val, err := reqState.ValidatorAtIndex(uint64(i)) if err != nil { return nil, status.Error(codes.Internal, "Could not get validator") } @@ -406,7 +417,7 @@ func (bs *Server) ListValidators( } } - if requestedEpoch < currentEpoch { + if !featureconfig.Get().NewStateMgmt && requestedEpoch < currentEpoch { stopIdx := len(validatorList) for idx, item := range validatorList { // The first time we see a validator with an activation epoch > the requested epoch, diff --git a/beacon-chain/rpc/beacon/validators_test.go b/beacon-chain/rpc/beacon/validators_test.go index 5b9cd11c5c..5bea38d7b2 100644 --- a/beacon-chain/rpc/beacon/validators_test.go +++ b/beacon-chain/rpc/beacon/validators_test.go @@ -17,6 +17,7 @@ import ( "github.com/prysmaticlabs/go-bitfield" "github.com/prysmaticlabs/go-ssz" mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" + "github.com/prysmaticlabs/prysm/beacon-chain/cache" "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute" "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/beacon-chain/db" @@ -617,7 +618,13 @@ func TestServer_ListValidators_NoResults(t *testing.T) { if err := st.SetSlot(0); err != nil { t.Fatal(err) } - + gRoot := [32]byte{'g'} + 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{ BeaconDB: db, GenesisTimeFetcher: &mock.ChainService{ @@ -627,6 +634,7 @@ func TestServer_ListValidators_NoResults(t *testing.T) { HeadFetcher: &mock.ChainService{ State: st, }, + StateGen: stategen.New(db, cache.NewStateSummaryCache()), } wanted := ðpb.Validators{ ValidatorList: make([]*ethpb.Validators_ValidatorContainer, 0),