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 back archival endpoint GetValidatorActiveSetChanges with fallback #5519

Merged
merged 25 commits into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0065320
Modify `GetValidatorActiveSetChanges` to use new state service (#5408)
terencechain Apr 15, 2020
5651f17
Active set chagne with fallback
terencechain Apr 19, 2020
ac42318
Add back the old tests
terencechain Apr 19, 2020
a498998
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 19, 2020
7168b96
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
348a0a9
Conflict
terencechain Apr 20, 2020
96ae047
Merge branch 'active-set-change-fallback' of github.com:prysmaticlabs…
terencechain Apr 20, 2020
7f0df35
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
4b9a31e
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
bcacd19
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
e15799b
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
1e785f0
Merge branch 'master' of github.com:prysmaticlabs/prysm into active-s…
terencechain Apr 20, 2020
8625d48
Fixed test
terencechain Apr 20, 2020
4d99ca4
Merge branch 'active-set-change-fallback' of github.com:prysmaticlabs…
terencechain Apr 20, 2020
a886fd7
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
22b9d1c
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
3de7825
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
9e2bf95
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
3f47286
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
0e4a780
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
c4ce5ff
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
bb65efe
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
adea2a0
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
9d7a6ad
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
061f29e
Merge refs/heads/master into active-set-change-fallback
prylabs-bulldozer[bot] Apr 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions beacon-chain/rpc/beacon/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,94 @@ func (bs *Server) GetValidator(
func (bs *Server) GetValidatorActiveSetChanges(
ctx context.Context, req *ethpb.GetValidatorActiveSetChangesRequest,
) (*ethpb.ActiveSetChanges, error) {

if featureconfig.Get().DisableNewStateMgmt {
return bs.getValidatorActiveSetChangesUsingOldArchival(ctx, req)
}

currentEpoch := helpers.SlotToEpoch(bs.GenesisTimeFetcher.CurrentSlot())

var requestedEpoch uint64
switch q := req.QueryFilter.(type) {
case *ethpb.GetValidatorActiveSetChangesRequest_Genesis:
requestedEpoch = 0
case *ethpb.GetValidatorActiveSetChangesRequest_Epoch:
requestedEpoch = q.Epoch
default:
requestedEpoch = currentEpoch
}
if requestedEpoch > currentEpoch {
return nil, status.Errorf(
codes.InvalidArgument,
"Cannot retrieve information about an epoch in the future, current epoch %d, requesting %d",
currentEpoch,
requestedEpoch,
)
}

activatedIndices := make([]uint64, 0)
exitedIndices := make([]uint64, 0)
slashedIndices := make([]uint64, 0)
ejectedIndices := make([]uint64, 0)

requestedState, err := bs.StateGen.StateBySlot(ctx, helpers.StartSlot(requestedEpoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
}

activeValidatorCount, err := helpers.ActiveValidatorCount(requestedState, helpers.CurrentEpoch(requestedState))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get active validator count: %v", err)
}
vs := requestedState.Validators()
activatedIndices = validators.ActivatedValidatorIndices(helpers.CurrentEpoch(requestedState), vs)
exitedIndices, err = validators.ExitedValidatorIndices(helpers.CurrentEpoch(requestedState), vs, activeValidatorCount)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not determine exited validator indices: %v", err)
}
slashedIndices = validators.SlashedValidatorIndices(helpers.CurrentEpoch(requestedState), vs)
ejectedIndices, err = validators.EjectedValidatorIndices(helpers.CurrentEpoch(requestedState), vs, activeValidatorCount)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not determine ejected validator indices: %v", err)
}

// Retrieve public keys for the indices.
activatedKeys := make([][]byte, len(activatedIndices))
exitedKeys := make([][]byte, len(exitedIndices))
slashedKeys := make([][]byte, len(slashedIndices))
ejectedKeys := make([][]byte, len(ejectedIndices))
for i, idx := range activatedIndices {
pubkey := requestedState.PubkeyAtIndex(idx)
activatedKeys[i] = pubkey[:]
}
for i, idx := range exitedIndices {
pubkey := requestedState.PubkeyAtIndex(idx)
exitedKeys[i] = pubkey[:]
}
for i, idx := range slashedIndices {
pubkey := requestedState.PubkeyAtIndex(idx)
slashedKeys[i] = pubkey[:]
}
for i, idx := range ejectedIndices {
pubkey := requestedState.PubkeyAtIndex(idx)
ejectedKeys[i] = pubkey[:]
}
return &ethpb.ActiveSetChanges{
Epoch: requestedEpoch,
ActivatedPublicKeys: activatedKeys,
ActivatedIndices: activatedIndices,
ExitedPublicKeys: exitedKeys,
ExitedIndices: exitedIndices,
SlashedPublicKeys: slashedKeys,
SlashedIndices: slashedIndices,
EjectedPublicKeys: ejectedKeys,
EjectedIndices: ejectedIndices,
}, nil
}

func (bs *Server) getValidatorActiveSetChangesUsingOldArchival(
ctx context.Context, req *ethpb.GetValidatorActiveSetChangesRequest,
) (*ethpb.ActiveSetChanges, error) {
headState, err := bs.HeadFetcher.HeadState(ctx)
if err != nil {
return nil, status.Error(codes.Internal, "Could not get head state")
Expand Down
78 changes: 47 additions & 31 deletions beacon-chain/rpc/beacon/validators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,27 @@ func init() {
})
}

func TestServer_GetValidatorActiveSetChanges_CannotRequestFutureEpoch(t *testing.T) {
ctx := context.Background()
st := testutil.NewBeaconState()
if err := st.SetSlot(0); err != nil {
t.Fatal(err)
}
bs := &Server{GenesisTimeFetcher: &mock.ChainService{}}

wanted := "Cannot retrieve information about an epoch in the future"
if _, err := bs.GetValidatorActiveSetChanges(
ctx,
&ethpb.GetValidatorActiveSetChangesRequest{
QueryFilter: &ethpb.GetValidatorActiveSetChangesRequest_Epoch{
Epoch: helpers.SlotToEpoch(bs.GenesisTimeFetcher.CurrentSlot()) + 1,
},
},
); err != nil && !strings.Contains(err.Error(), wanted) {
t.Errorf("Expected error %v, received %v", wanted, err)
}
}

func TestServer_ListValidatorBalances_CannotRequestFutureEpoch(t *testing.T) {
db := dbTest.SetupDB(t)
defer dbTest.TeardownDB(t, db)
Expand Down Expand Up @@ -1123,36 +1144,10 @@ func TestServer_GetValidator(t *testing.T) {
}
}

func TestServer_GetValidatorActiveSetChanges_CannotRequestFutureEpoch(t *testing.T) {
func TestServer_GetValidatorActiveSetChanges(t *testing.T) {
db := dbTest.SetupDB(t)
defer dbTest.TeardownDB(t, db)

ctx := context.Background()
st := testutil.NewBeaconState()
if err := st.SetSlot(0); err != nil {
t.Fatal(err)
}
bs := &Server{
BeaconDB: db,
HeadFetcher: &mock.ChainService{
State: st,
},
}

wanted := "Cannot retrieve information about an epoch in the future"
if _, err := bs.GetValidatorActiveSetChanges(
ctx,
&ethpb.GetValidatorActiveSetChangesRequest{
QueryFilter: &ethpb.GetValidatorActiveSetChangesRequest_Epoch{
Epoch: 1,
},
},
); err != nil && !strings.Contains(err.Error(), wanted) {
t.Errorf("Expected error %v, received %v", wanted, err)
}
}

func TestServer_GetValidatorActiveSetChanges(t *testing.T) {
ctx := context.Background()
validators := make([]*ethpb.Validator, 8)
headState := testutil.NewBeaconState()
Expand Down Expand Up @@ -1197,15 +1192,32 @@ func TestServer_GetValidatorActiveSetChanges(t *testing.T) {
t.Fatal(err)
}
}
b := &ethpb.SignedBeaconBlock{Block: &ethpb.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)
}

bs := &Server{
HeadFetcher: &mock.ChainService{
State: headState,
},
FinalizationFetcher: &mock.ChainService{
FinalizedCheckPoint: &ethpb.Checkpoint{Epoch: 0},
},
GenesisTimeFetcher: &mock.ChainService{},
StateGen: stategen.New(db, cache.NewStateSummaryCache()),
}
res, err := bs.GetValidatorActiveSetChanges(ctx, &ethpb.GetValidatorActiveSetChangesRequest{})
res, err := bs.GetValidatorActiveSetChanges(ctx, &ethpb.GetValidatorActiveSetChangesRequest{
QueryFilter: &ethpb.GetValidatorActiveSetChangesRequest_Genesis{Genesis: true},
})
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1245,6 +1257,10 @@ func TestServer_GetValidatorActiveSetChanges(t *testing.T) {
}

func TestServer_GetValidatorActiveSetChanges_FromArchive(t *testing.T) {
fc := featureconfig.Get()
fc.DisableNewStateMgmt = true
featureconfig.Init(fc)

db := dbTest.SetupDB(t)
defer dbTest.TeardownDB(t, db)
ctx := context.Background()
Expand Down