mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 21:08:10 -05:00
Improve validator status method (#4032)
* Cleanup validatorStatus * gaz * fix tests * fix tests
This commit is contained in:
@@ -22,8 +22,10 @@ go_library(
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/traceutil:go_default_library",
|
||||
"@com_github_gogo_protobuf//types:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
"@org_golang_google_grpc//codes:go_default_library",
|
||||
"@org_golang_google_grpc//status:go_default_library",
|
||||
],
|
||||
|
||||
@@ -149,11 +149,6 @@ func TestWaitForActivation_ValidatorOriginallyExists(t *testing.T) {
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
PublicKey: pubKey1,
|
||||
},
|
||||
{
|
||||
ActivationEpoch: 0,
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
PublicKey: pubKey2,
|
||||
},
|
||||
},
|
||||
}
|
||||
block := blk.NewGenesisBlock([]byte{})
|
||||
|
||||
@@ -11,8 +11,12 @@ import (
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/traceutil"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
var errPubkeyDoesNotExist = errors.New("pubkey does not exist")
|
||||
|
||||
// ValidatorStatus returns the validator status of the current epoch.
|
||||
// The status response can be one of the following:
|
||||
// PENDING_ACTIVE - validator is waiting to get activated.
|
||||
@@ -62,54 +66,53 @@ func (vs *Server) multipleValidatorStatus(
|
||||
}
|
||||
|
||||
func (vs *Server) validatorStatus(ctx context.Context, pubKey []byte, headState *pbp2p.BeaconState) *pb.ValidatorStatusResponse {
|
||||
ctx, span := trace.StartSpan(ctx, "validatorServer.validatorStatus")
|
||||
defer span.End()
|
||||
|
||||
resp := &pb.ValidatorStatusResponse{
|
||||
Status: pb.ValidatorStatus_UNKNOWN_STATUS,
|
||||
ActivationEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
}
|
||||
vStatus, idx, err := vs.retrieveStatusFromState(ctx, pubKey, headState)
|
||||
if err != nil && err != errPubkeyDoesNotExist {
|
||||
traceutil.AnnotateError(span, err)
|
||||
return resp
|
||||
}
|
||||
resp.Status = vStatus
|
||||
if err != errPubkeyDoesNotExist {
|
||||
resp.ActivationEpoch = headState.Validators[idx].ActivationEpoch
|
||||
}
|
||||
|
||||
// If no connection to ETH1, the deposit block number or position in queue cannot be determined.
|
||||
if !vs.Eth1InfoFetcher.IsConnectedToETH1() {
|
||||
vStatus, idx, err := vs.retrieveStatusFromState(ctx, pubKey, headState)
|
||||
if err != nil {
|
||||
return &pb.ValidatorStatusResponse{
|
||||
Status: pb.ValidatorStatus_UNKNOWN_STATUS,
|
||||
ActivationEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
}
|
||||
}
|
||||
statusResp := &pb.ValidatorStatusResponse{
|
||||
Status: vStatus,
|
||||
}
|
||||
if vStatus == pb.ValidatorStatus_ACTIVE {
|
||||
statusResp.ActivationEpoch = headState.Validators[idx].ActivationEpoch
|
||||
}
|
||||
return statusResp
|
||||
log.Warn("Not connected to ETH1. Cannot determine validator ETH1 deposit block number")
|
||||
return resp
|
||||
}
|
||||
|
||||
_, eth1BlockNumBigInt := vs.DepositFetcher.DepositByPubkey(ctx, pubKey)
|
||||
if eth1BlockNumBigInt == nil {
|
||||
return &pb.ValidatorStatusResponse{
|
||||
Status: pb.ValidatorStatus_UNKNOWN_STATUS,
|
||||
ActivationEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
}
|
||||
if eth1BlockNumBigInt == nil { // No deposit found in ETH1.
|
||||
return resp
|
||||
}
|
||||
|
||||
statusResp := &pb.ValidatorStatusResponse{
|
||||
Status: pb.ValidatorStatus_DEPOSIT_RECEIVED,
|
||||
ActivationEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
Eth1DepositBlockNumber: eth1BlockNumBigInt.Uint64(),
|
||||
if resp.Status == pb.ValidatorStatus_UNKNOWN_STATUS {
|
||||
resp.Status = pb.ValidatorStatus_DEPOSIT_RECEIVED
|
||||
}
|
||||
|
||||
resp.Eth1DepositBlockNumber = eth1BlockNumBigInt.Uint64()
|
||||
|
||||
depositBlockSlot, err := vs.depositBlockSlot(ctx, headState.Slot, eth1BlockNumBigInt, headState)
|
||||
if err != nil {
|
||||
return statusResp
|
||||
return resp
|
||||
}
|
||||
statusResp.DepositInclusionSlot = depositBlockSlot
|
||||
vStatus, idx, err := vs.retrieveStatusFromState(ctx, pubKey, headState)
|
||||
if err != nil {
|
||||
return statusResp
|
||||
}
|
||||
statusResp.Status = vStatus
|
||||
resp.DepositInclusionSlot = depositBlockSlot
|
||||
|
||||
if vStatus == pb.ValidatorStatus_ACTIVE {
|
||||
statusResp.ActivationEpoch = headState.Validators[idx].ActivationEpoch
|
||||
return statusResp
|
||||
// If validator has been activated at any point, they are not in the queue so we can return
|
||||
// the request early. Additionally, if idx is zero (default return value) then we know this
|
||||
// validator cannot be in the queue either.
|
||||
if resp.ActivationEpoch != params.BeaconConfig().FarFutureEpoch || idx == 0 {
|
||||
return resp
|
||||
}
|
||||
|
||||
var queuePosition uint64
|
||||
var lastActivatedValidatorIdx uint64
|
||||
for j := len(headState.Validators) - 1; j >= 0; j-- {
|
||||
if helpers.IsActiveValidator(headState.Validators[j], helpers.CurrentEpoch(headState)) {
|
||||
@@ -118,14 +121,11 @@ func (vs *Server) validatorStatus(ctx context.Context, pubKey []byte, headState
|
||||
}
|
||||
}
|
||||
// Our position in the activation queue is the above index - our validator index.
|
||||
queuePosition = idx - lastActivatedValidatorIdx
|
||||
return &pb.ValidatorStatusResponse{
|
||||
Status: vStatus,
|
||||
Eth1DepositBlockNumber: eth1BlockNumBigInt.Uint64(),
|
||||
PositionInActivationQueue: queuePosition,
|
||||
DepositInclusionSlot: depositBlockSlot,
|
||||
ActivationEpoch: headState.Validators[idx].ActivationEpoch,
|
||||
if lastActivatedValidatorIdx > idx {
|
||||
resp.PositionInActivationQueue = idx - lastActivatedValidatorIdx
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
func (vs *Server) retrieveStatusFromState(ctx context.Context, pubKey []byte,
|
||||
@@ -137,8 +137,8 @@ func (vs *Server) retrieveStatusFromState(ctx context.Context, pubKey []byte,
|
||||
if err != nil {
|
||||
return pb.ValidatorStatus(0), 0, err
|
||||
}
|
||||
if !ok {
|
||||
return pb.ValidatorStatus(0), 0, errors.New("pubkey does not exist")
|
||||
if !ok || int(idx) >= len(headState.Validators) {
|
||||
return pb.ValidatorStatus(0), 0, errPubkeyDoesNotExist
|
||||
}
|
||||
return vs.assignmentStatus(idx, headState), idx, nil
|
||||
}
|
||||
|
||||
@@ -524,6 +524,7 @@ func TestValidatorStatus_UnknownStatus(t *testing.T) {
|
||||
Slot: 0,
|
||||
},
|
||||
},
|
||||
BeaconDB: db,
|
||||
}
|
||||
req := &pb.ValidatorIndexRequest{
|
||||
PublicKey: pubKey,
|
||||
@@ -543,27 +544,19 @@ func TestMultipleValidatorStatus_OK(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
pubKeys := [][]byte{{'A'}, {'B'}, {'C'}}
|
||||
if err := db.SaveValidatorIndex(ctx, bytesutil.ToBytes48(pubKeys[0]), 0); err != nil {
|
||||
t.Fatalf("Could not save validator index: %v", err)
|
||||
}
|
||||
if err := db.SaveValidatorIndex(ctx, bytesutil.ToBytes48(pubKeys[1]), 0); err != nil {
|
||||
t.Fatalf("Could not save validator index: %v", err)
|
||||
}
|
||||
|
||||
beaconState := &pbp2p.BeaconState{
|
||||
Slot: 4000,
|
||||
Validators: []*ethpb.Validator{{
|
||||
ActivationEpoch: 0,
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
PublicKey: pubKeys[0]},
|
||||
Validators: []*ethpb.Validator{
|
||||
{
|
||||
ActivationEpoch: 0,
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
PublicKey: pubKeys[1]},
|
||||
PublicKey: pubKeys[0],
|
||||
},
|
||||
{
|
||||
ActivationEpoch: 0,
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
PublicKey: pubKeys[2]},
|
||||
PublicKey: pubKeys[1],
|
||||
},
|
||||
},
|
||||
}
|
||||
block := blk.NewGenesisBlock([]byte{})
|
||||
@@ -606,9 +599,6 @@ func TestMultipleValidatorStatus_OK(t *testing.T) {
|
||||
if err := db.SaveValidatorIndex(ctx, bytesutil.ToBytes48(pubKeys[1]), 1); err != nil {
|
||||
t.Fatalf("could not save validator index: %v", err)
|
||||
}
|
||||
if err := db.SaveValidatorIndex(ctx, bytesutil.ToBytes48(pubKeys[2]), 2); err != nil {
|
||||
t.Fatalf("could not save validator index: %v", err)
|
||||
}
|
||||
vs := &Server{
|
||||
BeaconDB: db,
|
||||
Ctx: context.Background(),
|
||||
@@ -631,12 +621,12 @@ func TestMultipleValidatorStatus_OK(t *testing.T) {
|
||||
response[0].PublicKey, response[0].Status.Status.String())
|
||||
}
|
||||
|
||||
if response[1].Status.Status == pb.ValidatorStatus_ACTIVE {
|
||||
if response[1].Status.Status != pb.ValidatorStatus_ACTIVE {
|
||||
t.Errorf("Validator with pubkey %#x was activated when not supposed to",
|
||||
response[1].PublicKey)
|
||||
}
|
||||
|
||||
if response[2].Status.Status != pb.ValidatorStatus_ACTIVE {
|
||||
if response[2].Status.Status != pb.ValidatorStatus_DEPOSIT_RECEIVED {
|
||||
t.Errorf("Validator with pubkey %#x is not activated and instead has this status: %s",
|
||||
response[2].PublicKey, response[2].Status.Status.String())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user