Filter ListValidators by Active in RPC (#4061)

* update workspace

* include active filter

* fix up latest changes to match naming

* better comments, fix evaluators

* latest master

* filter items

* filter only active validators
This commit is contained in:
Raul Jordan
2019-11-21 14:29:24 -06:00
committed by GitHub
parent a264a097cc
commit 8f8d2d36c0
2 changed files with 71 additions and 7 deletions

View File

@@ -187,10 +187,10 @@ func (bs *Server) ListValidators(
requestedEpoch = q.Epoch
}
validators := headState.Validators
vals := headState.Validators
if requestedEpoch < currentEpoch {
stopIdx := len(validators)
for idx, val := range validators {
stopIdx := len(vals)
for idx, val := range vals {
// The first time we see a validator with an activation epoch > the requested epoch,
// we know this validator is from the future relative to what the request wants.
if val.ActivationEpoch > requestedEpoch {
@@ -198,7 +198,7 @@ func (bs *Server) ListValidators(
break
}
}
validators = validators[:stopIdx]
vals = vals[:stopIdx]
} else if requestedEpoch > currentEpoch {
// Otherwise, we are requesting data from the future and we return an error.
return nil, status.Errorf(
@@ -209,8 +209,20 @@ func (bs *Server) ListValidators(
)
}
validatorCount := len(validators)
// If there are no validators, we simply return a response specifying this.
// Filter active validators if the request specifies it.
res := vals
if req.Active {
filteredValidators := make([]*ethpb.Validator, 0)
for _, val := range vals {
if helpers.IsActiveValidator(val, requestedEpoch) {
filteredValidators = append(filteredValidators, val)
}
}
res = filteredValidators
}
validatorCount := len(res)
// If there are no items, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 validators below would result in an error.
if validatorCount == 0 {
return &ethpb.Validators{
@@ -230,7 +242,7 @@ func (bs *Server) ListValidators(
}
return &ethpb.Validators{
Validators: validators[start:end],
Validators: res[start:end],
TotalSize: int32(validatorCount),
NextPageToken: nextPageToken,
}, nil

View File

@@ -430,6 +430,58 @@ func TestServer_ListValidators_NoResults(t *testing.T) {
}
}
func TestServer_ListValidators_OnlyActiveValidators(t *testing.T) {
db := dbTest.SetupDB(t)
defer dbTest.TeardownDB(t, db)
ctx := context.Background()
count := 100
balances := make([]uint64, count)
validators := make([]*ethpb.Validator, count)
activeValidators := make([]*ethpb.Validator, 0)
for i := 0; i < count; i++ {
if err := db.SaveValidatorIndex(ctx, [48]byte{byte(i)}, uint64(i)); err != nil {
t.Fatal(err)
}
balances[i] = params.BeaconConfig().MaxEffectiveBalance
// We mark even validators as active, and odd validators as inactive.
if i%2 == 0 {
val := &ethpb.Validator{
PublicKey: []byte{byte(i)},
ActivationEpoch: 0,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
}
validators[i] = val
activeValidators = append(activeValidators, val)
} else {
validators[i] = &ethpb.Validator{
PublicKey: []byte{byte(i)},
ActivationEpoch: 0,
ExitEpoch: 0,
}
}
}
headState := &pbp2p.BeaconState{Validators: validators, Balances: balances}
bs := &Server{
HeadFetcher: &mock.ChainService{
State: headState,
},
}
received, err := bs.ListValidators(context.Background(), &ethpb.ListValidatorsRequest{
Active: true,
})
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(activeValidators, received.Validators) {
t.Errorf("Wanted %v, received %v", activeValidators, received.Validators)
}
}
func TestServer_ListValidators_NoPagination(t *testing.T) {
db := dbTest.SetupDB(t)
defer dbTest.TeardownDB(t, db)