mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
ETH2 APIs: Handle invalid validator status as error (#8946)
* Handle invalid validator status as error * Change text * Fix review comments * Remove nil status check Co-authored-by: Radosław Kapka <rkapka@wp.pl>
This commit is contained in:
@@ -59,8 +59,14 @@ func (bs *Server) ListValidators(ctx context.Context, req *ethpb.StateValidators
|
||||
epoch := helpers.SlotToEpoch(state.Slot())
|
||||
filteredVals := make([]*ethpb.ValidatorContainer, 0, len(valContainers))
|
||||
for _, vc := range valContainers {
|
||||
valStatus := validatorStatus(vc.Validator, epoch)
|
||||
valSubStatus := validatorSubStatus(vc.Validator, epoch)
|
||||
valStatus, err := validatorStatus(vc.Validator, epoch)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get validator status: %v", err)
|
||||
}
|
||||
valSubStatus, err := validatorSubStatus(vc.Validator, epoch)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get validator sub status: %v", err)
|
||||
}
|
||||
if filterStatus[valStatus] || filterStatus[valSubStatus] {
|
||||
filteredVals = append(filteredVals, vc)
|
||||
}
|
||||
@@ -150,10 +156,14 @@ func valContainersByRequestIds(state iface.BeaconState, validatorIds [][]byte) (
|
||||
valContainers = make([]*ethpb.ValidatorContainer, len(allValidators))
|
||||
for i, validator := range allValidators {
|
||||
v1Validator := migration.V1Alpha1ValidatorToV1(validator)
|
||||
subStatus, err := validatorSubStatus(v1Validator, epoch)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get validator sub status: %v", err)
|
||||
}
|
||||
valContainers[i] = ðpb.ValidatorContainer{
|
||||
Index: types.ValidatorIndex(i),
|
||||
Balance: allBalances[i],
|
||||
Status: validatorSubStatus(v1Validator, epoch),
|
||||
Status: subStatus,
|
||||
Validator: v1Validator,
|
||||
}
|
||||
}
|
||||
@@ -175,10 +185,14 @@ func valContainersByRequestIds(state iface.BeaconState, validatorIds [][]byte) (
|
||||
valIndex = types.ValidatorIndex(index)
|
||||
}
|
||||
v1Validator := migration.V1Alpha1ValidatorToV1(allValidators[valIndex])
|
||||
subStatus, err := validatorSubStatus(v1Validator, epoch)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get validator sub status: %v", err)
|
||||
}
|
||||
valContainers[i] = ðpb.ValidatorContainer{
|
||||
Index: valIndex,
|
||||
Balance: allBalances[valIndex],
|
||||
Status: validatorSubStatus(v1Validator, epoch),
|
||||
Status: subStatus,
|
||||
Validator: v1Validator,
|
||||
}
|
||||
}
|
||||
@@ -186,59 +200,63 @@ func valContainersByRequestIds(state iface.BeaconState, validatorIds [][]byte) (
|
||||
return valContainers, nil
|
||||
}
|
||||
|
||||
func validatorStatus(validator *ethpb.Validator, epoch types.Epoch) ethpb.ValidatorStatus {
|
||||
switch validatorSubStatus(validator, epoch) {
|
||||
case ethpb.ValidatorStatus_PENDING_INITIALIZED, ethpb.ValidatorStatus_PENDING_QUEUED:
|
||||
return ethpb.ValidatorStatus_PENDING
|
||||
case ethpb.ValidatorStatus_ACTIVE_ONGOING, ethpb.ValidatorStatus_ACTIVE_SLASHED, ethpb.ValidatorStatus_ACTIVE_EXITING:
|
||||
return ethpb.ValidatorStatus_ACTIVE
|
||||
case ethpb.ValidatorStatus_EXITED_UNSLASHED, ethpb.ValidatorStatus_EXITED_SLASHED:
|
||||
return ethpb.ValidatorStatus_EXITED
|
||||
case ethpb.ValidatorStatus_WITHDRAWAL_POSSIBLE, ethpb.ValidatorStatus_WITHDRAWAL_DONE:
|
||||
return ethpb.ValidatorStatus_WITHDRAWAL
|
||||
func validatorStatus(validator *ethpb.Validator, epoch types.Epoch) (ethpb.ValidatorStatus, error) {
|
||||
valStatus, err := validatorSubStatus(validator, epoch)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not get sub status")
|
||||
}
|
||||
return 0
|
||||
switch valStatus {
|
||||
case ethpb.ValidatorStatus_PENDING_INITIALIZED, ethpb.ValidatorStatus_PENDING_QUEUED:
|
||||
return ethpb.ValidatorStatus_PENDING, nil
|
||||
case ethpb.ValidatorStatus_ACTIVE_ONGOING, ethpb.ValidatorStatus_ACTIVE_SLASHED, ethpb.ValidatorStatus_ACTIVE_EXITING:
|
||||
return ethpb.ValidatorStatus_ACTIVE, nil
|
||||
case ethpb.ValidatorStatus_EXITED_UNSLASHED, ethpb.ValidatorStatus_EXITED_SLASHED:
|
||||
return ethpb.ValidatorStatus_EXITED, nil
|
||||
case ethpb.ValidatorStatus_WITHDRAWAL_POSSIBLE, ethpb.ValidatorStatus_WITHDRAWAL_DONE:
|
||||
return ethpb.ValidatorStatus_WITHDRAWAL, nil
|
||||
}
|
||||
return 0, errors.New("invalid validator state")
|
||||
}
|
||||
|
||||
func validatorSubStatus(validator *ethpb.Validator, epoch types.Epoch) ethpb.ValidatorStatus {
|
||||
func validatorSubStatus(validator *ethpb.Validator, epoch types.Epoch) (ethpb.ValidatorStatus, error) {
|
||||
farFutureEpoch := params.BeaconConfig().FarFutureEpoch
|
||||
|
||||
// Pending.
|
||||
if validator.ActivationEpoch > epoch {
|
||||
if validator.ActivationEligibilityEpoch == farFutureEpoch {
|
||||
return ethpb.ValidatorStatus_PENDING_INITIALIZED
|
||||
} else if validator.ActivationEligibilityEpoch < farFutureEpoch && validator.ActivationEpoch > epoch {
|
||||
return ethpb.ValidatorStatus_PENDING_QUEUED
|
||||
return ethpb.ValidatorStatus_PENDING_INITIALIZED, nil
|
||||
} else if validator.ActivationEligibilityEpoch < farFutureEpoch {
|
||||
return ethpb.ValidatorStatus_PENDING_QUEUED, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Active.
|
||||
if validator.ActivationEpoch <= epoch && epoch < validator.ExitEpoch {
|
||||
if validator.ExitEpoch == farFutureEpoch {
|
||||
return ethpb.ValidatorStatus_ACTIVE_ONGOING
|
||||
return ethpb.ValidatorStatus_ACTIVE_ONGOING, nil
|
||||
} else if validator.ExitEpoch < farFutureEpoch {
|
||||
if validator.Slashed {
|
||||
return ethpb.ValidatorStatus_ACTIVE_SLASHED
|
||||
return ethpb.ValidatorStatus_ACTIVE_SLASHED, nil
|
||||
}
|
||||
return ethpb.ValidatorStatus_ACTIVE_EXITING
|
||||
return ethpb.ValidatorStatus_ACTIVE_EXITING, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Exited.
|
||||
if validator.ExitEpoch <= epoch && epoch < validator.WithdrawableEpoch {
|
||||
if validator.Slashed {
|
||||
return ethpb.ValidatorStatus_EXITED_SLASHED
|
||||
return ethpb.ValidatorStatus_EXITED_SLASHED, nil
|
||||
}
|
||||
return ethpb.ValidatorStatus_EXITED_UNSLASHED
|
||||
return ethpb.ValidatorStatus_EXITED_UNSLASHED, nil
|
||||
}
|
||||
|
||||
if validator.WithdrawableEpoch <= epoch {
|
||||
if validator.EffectiveBalance != 0 {
|
||||
return ethpb.ValidatorStatus_WITHDRAWAL_POSSIBLE
|
||||
return ethpb.ValidatorStatus_WITHDRAWAL_POSSIBLE, nil
|
||||
} else {
|
||||
return ethpb.ValidatorStatus_WITHDRAWAL_DONE
|
||||
return ethpb.ValidatorStatus_WITHDRAWAL_DONE, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
return 0, errors.New("invalid validator state")
|
||||
}
|
||||
|
||||
@@ -220,36 +220,48 @@ func TestListValidators_Status(t *testing.T) {
|
||||
|
||||
farFutureEpoch := params.BeaconConfig().FarFutureEpoch
|
||||
validators := []*ethpb_alpha.Validator{
|
||||
// Pending initialized.
|
||||
{
|
||||
ActivationEpoch: farFutureEpoch,
|
||||
ActivationEligibilityEpoch: farFutureEpoch,
|
||||
},
|
||||
// Pending queued.
|
||||
{
|
||||
ActivationEpoch: 10,
|
||||
ActivationEligibilityEpoch: 4,
|
||||
},
|
||||
// Active ongoing.
|
||||
{
|
||||
ActivationEpoch: 0,
|
||||
ExitEpoch: farFutureEpoch,
|
||||
},
|
||||
// Active slashed.
|
||||
{
|
||||
ActivationEpoch: 0,
|
||||
ExitEpoch: 30,
|
||||
Slashed: true,
|
||||
},
|
||||
// Active exiting.
|
||||
{
|
||||
ActivationEpoch: 3,
|
||||
ExitEpoch: 30,
|
||||
Slashed: false,
|
||||
},
|
||||
// Exit slashed (at epoch 35).
|
||||
{
|
||||
ActivationEpoch: 3,
|
||||
ExitEpoch: 30,
|
||||
WithdrawableEpoch: 40,
|
||||
Slashed: true,
|
||||
},
|
||||
// Exit unslashed (at epoch 35).
|
||||
{
|
||||
ActivationEpoch: 3,
|
||||
ExitEpoch: 30,
|
||||
WithdrawableEpoch: 40,
|
||||
Slashed: false,
|
||||
},
|
||||
// Withdrawable (at epoch 45).
|
||||
{
|
||||
ActivationEpoch: 3,
|
||||
ExitEpoch: 30,
|
||||
@@ -257,6 +269,7 @@ func TestListValidators_Status(t *testing.T) {
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
Slashed: false,
|
||||
},
|
||||
// Withdrawal done (at epoch 45).
|
||||
{
|
||||
ActivationEpoch: 3,
|
||||
ExitEpoch: 30,
|
||||
@@ -284,7 +297,8 @@ func TestListValidators_Status(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, len(resp.Data), 8192+2 /* 2 active */)
|
||||
for _, datum := range resp.Data {
|
||||
status := validatorStatus(datum.Validator, 0)
|
||||
status, err := validatorStatus(datum.Validator, 0)
|
||||
require.NoError(t, err)
|
||||
require.Equal(
|
||||
t,
|
||||
true,
|
||||
@@ -314,7 +328,8 @@ func TestListValidators_Status(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, len(resp.Data), 8192+1 /* 1 active_ongoing */)
|
||||
for _, datum := range resp.Data {
|
||||
status := validatorSubStatus(datum.Validator, 0)
|
||||
status, err := validatorSubStatus(datum.Validator, 0)
|
||||
require.NoError(t, err)
|
||||
require.Equal(
|
||||
t,
|
||||
true,
|
||||
@@ -343,7 +358,8 @@ func TestListValidators_Status(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 4 /* 4 exited */, len(resp.Data))
|
||||
for _, datum := range resp.Data {
|
||||
status := validatorStatus(datum.Validator, 35)
|
||||
status, err := validatorStatus(datum.Validator, 35)
|
||||
require.NoError(t, err)
|
||||
require.Equal(
|
||||
t,
|
||||
true,
|
||||
@@ -371,7 +387,8 @@ func TestListValidators_Status(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 4 /* 4 exited */, len(resp.Data))
|
||||
for _, datum := range resp.Data {
|
||||
status := validatorSubStatus(datum.Validator, 35)
|
||||
status, err := validatorSubStatus(datum.Validator, 35)
|
||||
require.NoError(t, err)
|
||||
require.Equal(
|
||||
t,
|
||||
true,
|
||||
@@ -399,8 +416,10 @@ func TestListValidators_Status(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2 /* 1 pending, 1 exited */, len(resp.Data))
|
||||
for _, datum := range resp.Data {
|
||||
status := validatorStatus(datum.Validator, 35)
|
||||
subStatus := validatorSubStatus(datum.Validator, 35)
|
||||
status, err := validatorStatus(datum.Validator, 35)
|
||||
require.NoError(t, err)
|
||||
subStatus, err := validatorSubStatus(datum.Validator, 35)
|
||||
require.NoError(t, err)
|
||||
require.Equal(
|
||||
t,
|
||||
true,
|
||||
@@ -650,9 +669,10 @@ func Test_validatorStatus(t *testing.T) {
|
||||
epoch types.Epoch
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want ethpb.ValidatorStatus
|
||||
name string
|
||||
args args
|
||||
want ethpb.ValidatorStatus
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "pending initialized",
|
||||
@@ -665,6 +685,17 @@ func Test_validatorStatus(t *testing.T) {
|
||||
},
|
||||
want: ethpb.ValidatorStatus_PENDING,
|
||||
},
|
||||
{
|
||||
name: "pending queued",
|
||||
args: args{
|
||||
validator: ðpb.Validator{
|
||||
ActivationEpoch: 10,
|
||||
ActivationEligibilityEpoch: 2,
|
||||
},
|
||||
epoch: types.Epoch(5),
|
||||
},
|
||||
want: ethpb.ValidatorStatus_PENDING,
|
||||
},
|
||||
{
|
||||
name: "active ongoing",
|
||||
args: args{
|
||||
@@ -757,8 +788,10 @@ func Test_validatorStatus(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := validatorStatus(tt.args.validator, tt.args.epoch); got != tt.want {
|
||||
t.Errorf("validatorStatus() = %v, want %v", got, tt.want)
|
||||
got, err := validatorStatus(tt.args.validator, tt.args.epoch)
|
||||
require.NoError(t, err)
|
||||
if got != tt.want {
|
||||
t.Errorf("validatorStatus() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -772,9 +805,10 @@ func Test_validatorSubStatus(t *testing.T) {
|
||||
epoch types.Epoch
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want ethpb.ValidatorStatus
|
||||
name string
|
||||
args args
|
||||
want ethpb.ValidatorStatus
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "pending initialized",
|
||||
@@ -787,6 +821,17 @@ func Test_validatorSubStatus(t *testing.T) {
|
||||
},
|
||||
want: ethpb.ValidatorStatus_PENDING_INITIALIZED,
|
||||
},
|
||||
{
|
||||
name: "pending queued",
|
||||
args: args{
|
||||
validator: ðpb.Validator{
|
||||
ActivationEpoch: 10,
|
||||
ActivationEligibilityEpoch: 2,
|
||||
},
|
||||
epoch: types.Epoch(5),
|
||||
},
|
||||
want: ethpb.ValidatorStatus_PENDING_QUEUED,
|
||||
},
|
||||
{
|
||||
name: "active ongoing",
|
||||
args: args{
|
||||
@@ -879,8 +924,10 @@ func Test_validatorSubStatus(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := validatorSubStatus(tt.args.validator, tt.args.epoch); got != tt.want {
|
||||
t.Errorf("validatorSubStatus() = %v, want %v", got, tt.want)
|
||||
got, err := validatorSubStatus(tt.args.validator, tt.args.epoch)
|
||||
require.NoError(t, err)
|
||||
if got != tt.want {
|
||||
t.Errorf("validatorSubStatus() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user