Productionize RPC Server Error Codes (#3994)

* carefully return grpc status codes in attester server

* import spacing

* work on status codes

* codes in validator

* most changes done

* gaz and imports

* done

* fix broken tests

* tests fixed
This commit is contained in:
Raul Jordan
2019-11-13 15:03:12 -06:00
committed by GitHub
parent fc7c530696
commit cd6e3e8a09
19 changed files with 151 additions and 137 deletions

View File

@@ -17,7 +17,6 @@ go_library(
"//proto/beacon/rpc/v1:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",

View File

@@ -4,7 +4,6 @@ import (
"context"
"github.com/gogo/protobuf/proto"
"github.com/pkg/errors"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
@@ -45,18 +44,18 @@ type Server struct {
func (as *Server) SubmitAttestation(ctx context.Context, att *ethpb.Attestation) (*pb.AttestResponse, error) {
root, err := ssz.HashTreeRoot(att.Data)
if err != nil {
return nil, errors.Wrap(err, "failed to hash tree root attestation")
return nil, status.Errorf(codes.Internal, "Failed to tree hash attestation: %v", err)
}
go func() {
ctx = trace.NewContext(context.Background(), trace.FromContext(ctx))
attCopy := proto.Clone(att).(*ethpb.Attestation)
if err := as.AttReceiver.ReceiveAttestation(ctx, att); err != nil {
log.WithError(err).Error("could not receive attestation in chain service")
log.WithError(err).Error("Could not receive attestation in chain service")
return
}
if err := as.OperationsHandler.HandleAttestation(ctx, attCopy); err != nil {
log.WithError(err).Error("could not handle attestation in operations service")
log.WithError(err).Error("Could not handle attestation in operations service")
return
}
}()
@@ -80,9 +79,8 @@ func (as *Server) RequestAttestation(ctx context.Context, req *pb.AttestationReq
res, err := as.AttestationCache.Get(ctx, req)
if err != nil {
return nil, err
return nil, status.Errorf(codes.Internal, "Could not retrieve data from attestation cache: %v", err)
}
if res != nil {
return res, nil
}
@@ -91,15 +89,14 @@ func (as *Server) RequestAttestation(ctx context.Context, req *pb.AttestationReq
if err == cache.ErrAlreadyInProgress {
res, err := as.AttestationCache.Get(ctx, req)
if err != nil {
return nil, err
return nil, status.Errorf(codes.Internal, "Could not retrieve data from attestation cache: %v", err)
}
if res == nil {
return nil, errors.New("a request was in progress and resolved to nil")
return nil, status.Error(codes.DataLoss, "A request was in progress and resolved to nil")
}
return res, nil
}
return nil, err
return nil, status.Errorf(codes.Internal, "Could not mark attestation as in-progress: %v", err)
}
defer func() {
if err := as.AttestationCache.MarkNotInProgress(req); err != nil {
@@ -114,21 +111,13 @@ func (as *Server) RequestAttestation(ctx context.Context, req *pb.AttestationReq
if headState == nil {
headState, err = as.BeaconDB.HeadState(ctx)
if err != nil {
return nil, err
}
}
// Safe guard against head state is nil in chain service. This should not happen.
if headState == nil {
headState, err = as.BeaconDB.HeadState(ctx)
if err != nil {
return nil, err
return nil, status.Errorf(codes.Internal, "Could not retrieve head state: %v", err)
}
}
headState, err = state.ProcessSlots(ctx, headState, req.Slot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to %d", req.Slot)
return nil, status.Errorf(codes.Internal, "Could not process slots up to %d: %v", req.Slot, err)
}
targetEpoch := helpers.CurrentEpoch(headState)
@@ -139,7 +128,7 @@ func (as *Server) RequestAttestation(ctx context.Context, req *pb.AttestationReq
} else {
targetRoot, err = helpers.BlockRootAtSlot(headState, epochStartSlot)
if err != nil {
return nil, errors.Wrapf(err, "could not get target block for slot %d", epochStartSlot)
return nil, status.Errorf(codes.Internal, "Could not get target block for slot %d: %v", epochStartSlot, err)
}
}
@@ -155,7 +144,7 @@ func (as *Server) RequestAttestation(ctx context.Context, req *pb.AttestationReq
}
if err := as.AttestationCache.Put(ctx, req, res); err != nil {
return nil, err
return nil, status.Errorf(codes.Internal, "Could not store attestation data in cache: %v", err)
}
return res, nil

View File

@@ -21,7 +21,7 @@ func (bs *Server) ListValidatorAssignments(
ctx context.Context, req *ethpb.ListValidatorAssignmentsRequest,
) (*ethpb.ValidatorAssignments, error) {
if int(req.PageSize) > params.BeaconConfig().MaxPageSize {
return nil, status.Errorf(codes.InvalidArgument, "requested page size %d can not be greater than max size %d",
return nil, status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
req.PageSize, params.BeaconConfig().MaxPageSize)
}
@@ -44,10 +44,10 @@ func (bs *Server) ListValidatorAssignments(
for _, pubKey := range req.PublicKeys {
index, ok, err := bs.BeaconDB.ValidatorIndex(ctx, bytesutil.ToBytes48(pubKey))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not retrieve validator index: %v", err)
return nil, status.Errorf(codes.Internal, "Could not retrieve validator index: %v", err)
}
if !ok {
return nil, status.Errorf(codes.NotFound, "could not find validator index for public key %#x not found", pubKey)
return nil, status.Errorf(codes.NotFound, "Could not find validator index for public key %#x", pubKey)
}
filtered[index] = true
filteredIndices = append(filteredIndices, index)
@@ -62,7 +62,7 @@ func (bs *Server) ListValidatorAssignments(
activeIndices, err := helpers.ActiveValidatorIndices(headState, requestedEpoch)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not retrieve active validator indices: %v", err)
return nil, status.Errorf(codes.Internal, "Could not retrieve active validator indices: %v", err)
}
if len(filteredIndices) == 0 {
// If no filter was specified, return assignments from active validator indices with pagination.
@@ -71,14 +71,14 @@ func (bs *Server) ListValidatorAssignments(
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(filteredIndices))
if err != nil {
return nil, err
return nil, status.Errorf(codes.Internal, "Could not paginate results: %v", err)
}
shouldFetchFromArchive := requestedEpoch < bs.FinalizationFetcher.FinalizedCheckpt().Epoch
for _, index := range filteredIndices[start:end] {
if int(index) >= len(headState.Validators) {
return nil, status.Errorf(codes.InvalidArgument, "validator index %d >= validator count %d",
return nil, status.Errorf(codes.OutOfRange, "Validator index %d >= validator count %d",
index, len(headState.Validators))
}
if shouldFetchFromArchive {
@@ -86,14 +86,14 @@ func (bs *Server) ListValidatorAssignments(
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not retrieve archived committee info for epoch %d",
"Could not retrieve archived committee info for epoch %d",
requestedEpoch,
)
}
if archivedInfo == nil {
return nil, status.Errorf(
codes.NotFound,
"no archival committee info found for epoch %d",
"Could not retrieve data for epoch %d, perhaps --archive in the running beacon node is disabled",
requestedEpoch,
)
}
@@ -101,14 +101,14 @@ func (bs *Server) ListValidatorAssignments(
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not retrieve archived balances for epoch %d",
"Could not retrieve archived balances for epoch %d",
requestedEpoch,
)
}
if archivedBalances == nil {
return nil, status.Errorf(
codes.NotFound,
"no archival balances found for epoch %d",
"Could not retrieve data for epoch %d, perhaps --archive in the running beacon node is disabled",
requestedEpoch,
)
}
@@ -120,7 +120,7 @@ func (bs *Server) ListValidatorAssignments(
archivedBalances,
)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not retrieve archived assignment for validator %d: %v", index, err)
return nil, status.Errorf(codes.Internal, "Could not retrieve archived assignment for validator %d: %v", index, err)
}
assign := &ethpb.ValidatorAssignments_CommitteeAssignment{
BeaconCommittees: committee,
@@ -134,7 +134,7 @@ func (bs *Server) ListValidatorAssignments(
}
committee, committeeIndex, attesterSlot, proposerSlot, err := helpers.CommitteeAssignment(headState, requestedEpoch, index)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not retrieve assignment for validator %d: %v", index, err)
return nil, status.Errorf(codes.Internal, "Could not retrieve assignment for validator %d: %v", index, err)
}
assign := &ethpb.ValidatorAssignments_CommitteeAssignment{
BeaconCommittees: committee,

View File

@@ -49,7 +49,7 @@ func TestServer_ListAssignments_Pagination_ExceedsMaxPageSize(t *testing.T) {
bs := &Server{}
exceedsMax := int32(params.BeaconConfig().MaxPageSize + 1)
wanted := fmt.Sprintf("requested page size %d can not be greater than max size %d", exceedsMax, params.BeaconConfig().MaxPageSize)
wanted := fmt.Sprintf("Requested page size %d can not be greater than max size %d", exceedsMax, params.BeaconConfig().MaxPageSize)
req := &ethpb.ListValidatorAssignmentsRequest{
PageToken: strconv.Itoa(0),
PageSize: exceedsMax,

View File

@@ -33,7 +33,7 @@ func (bs *Server) ListAttestations(
ctx context.Context, req *ethpb.ListAttestationsRequest,
) (*ethpb.ListAttestationsResponse, error) {
if int(req.PageSize) > params.BeaconConfig().MaxPageSize {
return nil, status.Errorf(codes.InvalidArgument, "requested page size %d can not be greater than max size %d",
return nil, status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
req.PageSize, params.BeaconConfig().MaxPageSize)
}
var atts []*ethpb.Attestation
@@ -42,30 +42,30 @@ func (bs *Server) ListAttestations(
case *ethpb.ListAttestationsRequest_HeadBlockRoot:
atts, err = bs.BeaconDB.Attestations(ctx, filters.NewFilter().SetHeadBlockRoot(q.HeadBlockRoot))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not fetch attestations: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
case *ethpb.ListAttestationsRequest_SourceEpoch:
atts, err = bs.BeaconDB.Attestations(ctx, filters.NewFilter().SetSourceEpoch(q.SourceEpoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not fetch attestations: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
case *ethpb.ListAttestationsRequest_SourceRoot:
atts, err = bs.BeaconDB.Attestations(ctx, filters.NewFilter().SetSourceRoot(q.SourceRoot))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not fetch attestations: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
case *ethpb.ListAttestationsRequest_TargetEpoch:
atts, err = bs.BeaconDB.Attestations(ctx, filters.NewFilter().SetTargetEpoch(q.TargetEpoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not fetch attestations: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
case *ethpb.ListAttestationsRequest_TargetRoot:
atts, err = bs.BeaconDB.Attestations(ctx, filters.NewFilter().SetTargetRoot(q.TargetRoot))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not fetch attestations: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
default:
return nil, status.Errorf(codes.Internal, "could not fetch attestations: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
// We sort attestations according to the Sortable interface.
sort.Sort(sortableAttestations(atts))
@@ -73,7 +73,7 @@ func (bs *Server) ListAttestations(
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), numAttestations)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not paginate attestations: %v", err)
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.ListAttestationsResponse{
Attestations: atts[start:end],
@@ -96,7 +96,7 @@ func (bs *Server) AttestationPool(
) (*ethpb.AttestationPoolResponse, error) {
atts, err := bs.Pool.AttestationPoolNoVerify(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not fetch attestations: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
return &ethpb.AttestationPoolResponse{
Attestations: atts,

View File

@@ -374,7 +374,7 @@ func TestServer_ListAttestations_Pagination_ExceedsMaxPageSize(t *testing.T) {
bs := &Server{}
exceedsMax := int32(params.BeaconConfig().MaxPageSize + 1)
wanted := fmt.Sprintf("requested page size %d can not be greater than max size %d", exceedsMax, params.BeaconConfig().MaxPageSize)
wanted := fmt.Sprintf("Requested page size %d can not be greater than max size %d", exceedsMax, params.BeaconConfig().MaxPageSize)
req := &ethpb.ListAttestationsRequest{PageToken: strconv.Itoa(0), PageSize: exceedsMax}
if _, err := bs.ListAttestations(ctx, req); !strings.Contains(err.Error(), wanted) {
t.Errorf("Expected error %v, received %v", wanted, err)

View File

@@ -23,7 +23,7 @@ func (bs *Server) ListBlocks(
ctx context.Context, req *ethpb.ListBlocksRequest,
) (*ethpb.ListBlocksResponse, error) {
if int(req.PageSize) > params.BeaconConfig().MaxPageSize {
return nil, status.Errorf(codes.InvalidArgument, "requested page size %d can not be greater than max size %d",
return nil, status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
req.PageSize, params.BeaconConfig().MaxPageSize)
}
@@ -34,7 +34,7 @@ func (bs *Server) ListBlocks(
blks, err := bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartSlot(startSlot).SetEndSlot(endSlot))
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get blocks: %v", err)
return nil, status.Errorf(codes.Internal, "Failed to get blocks: %v", err)
}
numBlks := len(blks)
@@ -44,7 +44,7 @@ func (bs *Server) ListBlocks(
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), numBlks)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not paginate blocks: %v", err)
return nil, status.Errorf(codes.Internal, "Could not paginate blocks: %v", err)
}
return &ethpb.ListBlocksResponse{
@@ -56,7 +56,7 @@ func (bs *Server) ListBlocks(
case *ethpb.ListBlocksRequest_Root:
blk, err := bs.BeaconDB.Block(ctx, bytesutil.ToBytes32(q.Root))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not retrieve block: %v", err)
return nil, status.Errorf(codes.Internal, "Could not retrieve block: %v", err)
}
if blk == nil {
@@ -71,7 +71,7 @@ func (bs *Server) ListBlocks(
case *ethpb.ListBlocksRequest_Slot:
blks, err := bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartSlot(q.Slot).SetEndSlot(q.Slot))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not retrieve blocks for slot %d: %v", q.Slot, err)
return nil, status.Errorf(codes.Internal, "Could not retrieve blocks for slot %d: %v", q.Slot, err)
}
numBlks := len(blks)
@@ -81,7 +81,7 @@ func (bs *Server) ListBlocks(
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), numBlks)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not paginate blocks: %v", err)
return nil, status.Errorf(codes.Internal, "Could not paginate blocks: %v", err)
}
return &ethpb.ListBlocksResponse{
@@ -91,7 +91,7 @@ func (bs *Server) ListBlocks(
}, nil
}
return nil, status.Errorf(codes.InvalidArgument, "must satisfy one of the filter requirement")
return nil, status.Errorf(codes.InvalidArgument, "Must satisfy one of the filter requirement")
}
// GetChainHead retrieves information about the head of the beacon chain from

View File

@@ -116,13 +116,13 @@ func TestServer_ListBlocks_Errors(t *testing.T) {
bs := &Server{BeaconDB: db}
exceedsMax := int32(params.BeaconConfig().MaxPageSize + 1)
wanted := fmt.Sprintf("requested page size %d can not be greater than max size %d", exceedsMax, params.BeaconConfig().MaxPageSize)
wanted := fmt.Sprintf("Requested page size %d can not be greater than max size %d", exceedsMax, params.BeaconConfig().MaxPageSize)
req := &ethpb.ListBlocksRequest{PageToken: strconv.Itoa(0), PageSize: exceedsMax}
if _, err := bs.ListBlocks(ctx, req); !strings.Contains(err.Error(), wanted) {
t.Errorf("Expected error %v, received %v", wanted, err)
}
wanted = "must satisfy one of the filter requirement"
wanted = "Must satisfy one of the filter requirement"
req = &ethpb.ListBlocksRequest{}
if _, err := bs.ListBlocks(ctx, req); !strings.Contains(err.Error(), wanted) {
t.Errorf("Expected error %v, received %v", wanted, err)

View File

@@ -23,7 +23,7 @@ func (bs *Server) ListBeaconCommittees(
if int(req.PageSize) > params.BeaconConfig().MaxPageSize {
return nil, status.Errorf(
codes.InvalidArgument,
"requested page size %d can not be greater than max size %d",
"Requested page size %d can not be greater than max size %d",
req.PageSize,
params.BeaconConfig().MaxPageSize,
)
@@ -51,7 +51,7 @@ func (bs *Server) ListBeaconCommittees(
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not retrieve active indices for epoch %d: %v",
"Could not retrieve active indices for epoch %d: %v",
helpers.SlotToEpoch(startSlot),
err,
)
@@ -60,7 +60,7 @@ func (bs *Server) ListBeaconCommittees(
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not request archival data for epoch %d: %v",
"Could not request archival data for epoch %d: %v",
helpers.SlotToEpoch(startSlot),
err,
)
@@ -68,7 +68,7 @@ func (bs *Server) ListBeaconCommittees(
if archivedCommitteeInfo == nil {
return nil, status.Errorf(
codes.NotFound,
"could not request data for epoch %d, perhaps --archive in the running beacon node is disabled",
"Could not retrieve data for epoch %d, perhaps --archive in the running beacon node is disabled",
helpers.SlotToEpoch(startSlot),
)
}
@@ -80,7 +80,7 @@ func (bs *Server) ListBeaconCommittees(
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not retrieve active indices for current epoch %d: %v",
"Could not retrieve active indices for current epoch %d: %v",
currentEpoch,
err,
)
@@ -89,7 +89,7 @@ func (bs *Server) ListBeaconCommittees(
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not retrieve attester seed for current epoch %d: %v",
"Could not retrieve attester seed for current epoch %d: %v",
currentEpoch,
err,
)
@@ -97,8 +97,8 @@ func (bs *Server) ListBeaconCommittees(
} else {
// Otherwise, we are requesting data from the future and we return an error.
return nil, status.Errorf(
codes.FailedPrecondition,
"cannot retrieve information about an epoch in the future, current epoch %d, requesting %d",
codes.InvalidArgument,
"Cannot retrieve information about an epoch in the future, current epoch %d, requesting %d",
helpers.SlotToEpoch(headState.Slot),
helpers.StartSlot(startSlot),
)
@@ -120,7 +120,7 @@ func (bs *Server) ListBeaconCommittees(
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not compute committee for slot %d: %v",
"Could not compute committee for slot %d: %v",
slot,
err,
)
@@ -136,8 +136,8 @@ func (bs *Server) ListBeaconCommittees(
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), numCommittees)
if err != nil {
return nil, status.Errorf(
codes.FailedPrecondition,
"could not paginate results: %v",
codes.Internal,
"Could not paginate results: %v",
err,
)
}

View File

@@ -59,7 +59,7 @@ func TestServer_ListBeaconCommittees_Pagination_ExceedsMaxPageSize(t *testing.T)
exceedsMax := int32(params.BeaconConfig().MaxPageSize + 1)
wanted := fmt.Sprintf(
"requested page size %d can not be greater than max size %d",
"Requested page size %d can not be greater than max size %d",
exceedsMax,
params.BeaconConfig().MaxPageSize,
)

View File

@@ -5,7 +5,6 @@ import (
"sort"
ptypes "github.com/gogo/protobuf/types"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
@@ -25,7 +24,7 @@ func (bs *Server) ListValidatorBalances(
req *ethpb.GetValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) {
if int(req.PageSize) > params.BeaconConfig().MaxPageSize {
return nil, status.Errorf(codes.InvalidArgument, "requested page size %d can not be greater than max size %d",
return nil, status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
req.PageSize, params.BeaconConfig().MaxPageSize)
}
@@ -50,12 +49,26 @@ func (bs *Server) ListValidatorBalances(
if requestingGenesis {
balances, err = bs.BeaconDB.ArchivedBalances(ctx, 0 /* genesis epoch */)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "could not retrieve balances for epoch %d", epoch)
return nil, status.Errorf(codes.Internal, "Could not retrieve balances for epoch %d", epoch)
}
if balances == nil {
return nil, status.Errorf(
codes.NotFound,
"Could not retrieve data for epoch %d, perhaps --archive in the running beacon node is disabled",
0,
)
}
} else if !requestingGenesis && epoch < helpers.CurrentEpoch(headState) {
balances, err = bs.BeaconDB.ArchivedBalances(ctx, epoch)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "could not retrieve balances for epoch %d", epoch)
return nil, status.Errorf(codes.Internal, "Could not retrieve balances for epoch %d", epoch)
}
if balances == nil {
return nil, status.Errorf(
codes.NotFound,
"Could not retrieve data for epoch %d, perhaps --archive in the running beacon node is disabled",
epoch,
)
}
} else {
balances = headState.Balances
@@ -69,16 +82,16 @@ func (bs *Server) ListValidatorBalances(
index, ok, err := bs.BeaconDB.ValidatorIndex(ctx, bytesutil.ToBytes48(pubKey))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not retrieve validator index: %v", err)
return nil, status.Errorf(codes.Internal, "Could not retrieve validator index: %v", err)
}
if !ok {
return nil, status.Errorf(codes.Internal, "could not find validator index for public key %#x not found", pubKey)
return nil, status.Errorf(codes.NotFound, "Could not find validator index for public key %#x", pubKey)
}
filtered[index] = true
if int(index) >= len(balances) {
return nil, status.Errorf(codes.OutOfRange, "validator index %d >= balance list %d",
return nil, status.Errorf(codes.OutOfRange, "Validator index %d >= balance list %d",
index, len(balances))
}
@@ -92,10 +105,10 @@ func (bs *Server) ListValidatorBalances(
for _, index := range req.Indices {
if int(index) >= len(balances) {
if epoch <= helpers.CurrentEpoch(headState) {
return nil, status.Errorf(codes.OutOfRange, "validator index %d does not exist in historical balances",
return nil, status.Errorf(codes.OutOfRange, "Validator index %d does not exist in historical balances",
index)
}
return nil, status.Errorf(codes.OutOfRange, "validator index %d >= balance list %d",
return nil, status.Errorf(codes.OutOfRange, "Validator index %d >= balance list %d",
index, len(balances))
}
@@ -122,7 +135,11 @@ func (bs *Server) ListValidatorBalances(
balancesCount := len(res)
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), balancesCount)
if err != nil {
return nil, err
return nil, status.Errorf(
codes.Internal,
"Could not paginate results: %v",
err,
)
}
return &ethpb.ValidatorBalances{
Epoch: epoch,
@@ -139,7 +156,7 @@ func (bs *Server) GetValidators(
req *ethpb.GetValidatorsRequest,
) (*ethpb.Validators, error) {
if int(req.PageSize) > params.BeaconConfig().MaxPageSize {
return nil, status.Errorf(codes.InvalidArgument, "requested page size %d can not be greater than max size %d",
return nil, status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
req.PageSize, params.BeaconConfig().MaxPageSize)
}
@@ -172,7 +189,11 @@ func (bs *Server) GetValidators(
validatorCount := len(validators)
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), validatorCount)
if err != nil {
return nil, err
return nil, status.Errorf(
codes.Internal,
"Could not paginate results: %v",
err,
)
}
return &ethpb.Validators{
@@ -209,7 +230,7 @@ func (bs *Server) GetValidatorActiveSetChanges(
if requestedEpoch < finalizedEpoch {
archivedChanges, err := bs.BeaconDB.ArchivedActiveValidatorChanges(ctx, requestedEpoch)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not fetch archived active validator changes: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch archived active validator changes: %v", err)
}
activatedIndices = archivedChanges.Activated
slashedIndices = archivedChanges.Slashed
@@ -219,7 +240,7 @@ func (bs *Server) GetValidatorActiveSetChanges(
slashedIndices = validators.SlashedValidatorIndices(headState)
exitedIndices, err = validators.ExitedValidatorIndices(headState)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not determine exited validator indices: %v", err)
return nil, status.Errorf(codes.Internal, "Could not determine exited validator indices: %v", err)
}
}
@@ -267,8 +288,8 @@ func (bs *Server) GetValidatorParticipation(
if requestedEpoch > helpers.SlotToEpoch(headState.Slot) {
return nil, status.Errorf(
codes.FailedPrecondition,
"cannot request data from an epoch in the future: req.Epoch %d, currentEpoch %d", requestedEpoch, currentEpoch,
codes.InvalidArgument,
"Cannot request data from an epoch in the future: req.Epoch %d, currentEpoch %d", requestedEpoch, currentEpoch,
)
}
// If the request is from genesis or another past epoch, we look into our archived
@@ -276,10 +297,14 @@ func (bs *Server) GetValidatorParticipation(
if isGenesis {
participation, err := bs.BeaconDB.ArchivedValidatorParticipation(ctx, 0)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not fetch archived participation: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch archived participation: %v", err)
}
if participation == nil {
return nil, status.Error(codes.NotFound, "could not find archival data for epoch 0")
return nil, status.Errorf(
codes.NotFound,
"Could not retrieve data for epoch %d, perhaps --archive in the running beacon node is disabled",
0,
)
}
return &ethpb.ValidatorParticipationResponse{
Epoch: 0,
@@ -289,10 +314,14 @@ func (bs *Server) GetValidatorParticipation(
} else if requestedEpoch < prevEpoch {
participation, err := bs.BeaconDB.ArchivedValidatorParticipation(ctx, requestedEpoch)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not fetch archived participation: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch archived participation: %v", err)
}
if participation == nil {
return nil, status.Errorf(codes.NotFound, "could not find archival data for epoch %d", requestedEpoch)
return nil, status.Errorf(
codes.NotFound,
"Could not retrieve data for epoch %d, perhaps --archive in the running beacon node is disabled",
requestedEpoch,
)
}
finalizedEpoch := bs.FinalizationFetcher.FinalizedCheckpt().Epoch
// If the epoch we requested is <= the finalized epoch, we consider it finalized as well.
@@ -307,7 +336,7 @@ func (bs *Server) GetValidatorParticipation(
// right away and return the result based on the head state.
participation, err := epoch.ComputeValidatorParticipation(headState, requestedEpoch)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not compute participation: %v", err)
return nil, status.Errorf(codes.Internal, "Could not compute participation: %v", err)
}
return &ethpb.ValidatorParticipationResponse{
Epoch: currentEpoch,
@@ -348,7 +377,7 @@ func (bs *Server) GetValidatorQueue(
activationQueueChurn := len(activationQ)
churnLimit, err := helpers.ValidatorChurnLimit(headState)
if err != nil {
return nil, errors.Wrap(err, "could not get churn limit")
return nil, status.Errorf(codes.Internal, "Could not compute churn limit: %v", err)
}
exitQueueEpoch := uint64(0)

View File

@@ -56,7 +56,7 @@ func TestServer_ListValidatorBalances_ExceedsMaxPageSize(t *testing.T) {
exceedsMax := int32(params.BeaconConfig().MaxPageSize + 1)
wanted := fmt.Sprintf(
"requested page size %d can not be greater than max size %d",
"Requested page size %d can not be greater than max size %d",
exceedsMax,
params.BeaconConfig().MaxPageSize,
)
@@ -451,7 +451,7 @@ func TestServer_GetValidators_ExceedsMaxPageSize(t *testing.T) {
bs := &Server{}
exceedsMax := int32(params.BeaconConfig().MaxPageSize + 1)
wanted := fmt.Sprintf("requested page size %d can not be greater than max size %d", exceedsMax, params.BeaconConfig().MaxPageSize)
wanted := fmt.Sprintf("Requested page size %d can not be greater than max size %d", exceedsMax, params.BeaconConfig().MaxPageSize)
req := &ethpb.GetValidatorsRequest{PageToken: strconv.Itoa(0), PageSize: exceedsMax}
if _, err := bs.GetValidators(context.Background(), req); !strings.Contains(err.Error(), wanted) {
t.Errorf("Expected error %v, received %v", wanted, err)

View File

@@ -36,12 +36,12 @@ func (ns *Server) GetSyncStatus(ctx context.Context, _ *ptypes.Empty) (*ethpb.Sy
func (ns *Server) GetGenesis(ctx context.Context, _ *ptypes.Empty) (*ethpb.Genesis, error) {
contractAddr, err := ns.BeaconDB.DepositContractAddress(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not retrieve contract address from db: %v", err)
return nil, status.Errorf(codes.Internal, "Could not retrieve contract address from db: %v", err)
}
genesisTime := ns.GenesisTimeFetcher.GenesisTime()
gt, err := ptypes.TimestampProto(genesisTime)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not convert genesis time to proto: %v", err)
return nil, status.Errorf(codes.Internal, "Could not convert genesis time to proto: %v", err)
}
return &ethpb.Genesis{
GenesisTime: gt,

View File

@@ -71,24 +71,24 @@ func (ps *Server) RequestBlock(ctx context.Context, req *pb.BlockRequest) (*ethp
parentRoot, err := ssz.SigningRoot(parent)
if err != nil {
return nil, errors.Wrap(err, "could not get parent block signing root")
return nil, status.Errorf(codes.Internal, "Could not get parent block signing root: %v", err)
}
eth1Data, err := ps.eth1Data(ctx, req.Slot)
if err != nil {
return nil, errors.Wrap(err, "could not get ETH1 data")
return nil, status.Errorf(codes.Internal, "Could not get ETH1 data: %v", err)
}
// Pack ETH1 deposits which have not been included in the beacon chain.
deposits, err := ps.deposits(ctx, eth1Data)
if err != nil {
return nil, errors.Wrap(err, "could not get eth1 deposits")
return nil, status.Errorf(codes.Internal, "Could not get ETH1 deposits: %v", err)
}
// Pack aggregated attestations which have not been included in the beacon chain.
atts, err := ps.Pool.AttestationPool(ctx, req.Slot)
if err != nil {
return nil, errors.Wrap(err, "could not get pending attestations")
return nil, status.Errorf(codes.Internal, "Could not get pending attestations: %v", err)
}
// Use zero hash as stub for state root to compute later.
@@ -118,7 +118,7 @@ func (ps *Server) RequestBlock(ctx context.Context, req *pb.BlockRequest) (*ethp
stateRoot, err = ps.computeStateRoot(ctx, blk)
if err != nil {
interop.WriteBlockToDisk(blk, true /*failed*/)
return nil, errors.Wrap(err, "could not get compute state root")
return nil, status.Errorf(codes.Internal, "Could not compute state root: %v", err)
}
blk.StateRoot = stateRoot
@@ -130,12 +130,12 @@ func (ps *Server) RequestBlock(ctx context.Context, req *pb.BlockRequest) (*ethp
func (ps *Server) ProposeBlock(ctx context.Context, blk *ethpb.BeaconBlock) (*pb.ProposeResponse, error) {
root, err := ssz.SigningRoot(blk)
if err != nil {
return nil, errors.Wrap(err, "could not tree hash block")
return nil, status.Errorf(codes.Internal, "Could not tree hash block: %v", err)
}
log.WithField("blockRoot", fmt.Sprintf("%#x", bytesutil.Trunc(root[:]))).Debugf(
"Block proposal received via RPC")
if err := ps.BlockReceiver.ReceiveBlock(ctx, blk); err != nil {
return nil, errors.Wrap(err, "could not process beacon block")
return nil, status.Errorf(codes.Internal, "Could not process beacon block: %v", err)
}
return &pb.ProposeResponse{BlockRoot: root[:]}, nil

View File

@@ -23,7 +23,6 @@ go_library(
"//shared/bytesutil:go_default_library",
"//shared/params:go_default_library",
"@com_github_gogo_protobuf//types:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@org_golang_google_grpc//codes:go_default_library",
"@org_golang_google_grpc//status:go_default_library",

View File

@@ -3,7 +3,6 @@ package validator
import (
"context"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
@@ -21,7 +20,7 @@ import (
// 4.) The bool signaling if the validator is expected to propose a block at the assigned slot.
func (vs *Server) CommitteeAssignment(ctx context.Context, req *pb.AssignmentRequest) (*pb.AssignmentResponse, error) {
if vs.SyncChecker.Syncing() {
return nil, status.Errorf(codes.Unavailable, "Syncing to latest head, not ready to respond")
return nil, status.Error(codes.Unavailable, "Syncing to latest head, not ready to respond")
}
var err error
@@ -30,16 +29,16 @@ func (vs *Server) CommitteeAssignment(ctx context.Context, req *pb.AssignmentReq
if epochStartSlot := helpers.StartSlot(req.EpochStart); s.Slot < epochStartSlot {
s, err = state.ProcessSlots(ctx, s, epochStartSlot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to %d", epochStartSlot)
return nil, status.Errorf(codes.Internal, "Could not process slots up to %d: %v", epochStartSlot, err)
}
}
var assignments []*pb.AssignmentResponse_ValidatorAssignment
for _, pubKey := range req.PublicKeys {
if ctx.Err() != nil {
return nil, ctx.Err()
return nil, status.Errorf(codes.Aborted, "Could not continue fetching assignments: %v", ctx.Err())
}
// Default assignment
// Default assignment.
assignment := &pb.AssignmentResponse_ValidatorAssignment{
PublicKey: pubKey,
Status: pb.ValidatorStatus_UNKNOWN_STATUS,
@@ -47,15 +46,15 @@ func (vs *Server) CommitteeAssignment(ctx context.Context, req *pb.AssignmentReq
idx, ok, err := vs.BeaconDB.ValidatorIndex(ctx, bytesutil.ToBytes48(pubKey))
if err != nil {
return nil, err
return nil, status.Errorf(codes.Internal, "Could not fetch validator idx for public key %#x: %v", pubKey, err)
}
if ok {
status := vs.assignmentStatus(uint64(idx), s)
assignment.Status = status
if status == pb.ValidatorStatus_ACTIVE {
assignment, err = vs.assignment(uint64(idx), s, req.EpochStart)
st := vs.assignmentStatus(idx, s)
assignment.Status = st
if st == pb.ValidatorStatus_ACTIVE {
assignment, err = vs.assignment(idx, s, req.EpochStart)
if err != nil {
return nil, err
return nil, status.Errorf(codes.Internal, "Could not fetch assignment for public key %#x: %v", pubKey, err)
}
assignment.PublicKey = pubKey
}
@@ -73,12 +72,11 @@ func (vs *Server) assignment(idx uint64, beaconState *pbp2p.BeaconState, epoch u
if err != nil {
return nil, err
}
status := vs.assignmentStatus(idx, beaconState)
return &pb.AssignmentResponse_ValidatorAssignment{
Committee: committee,
CommitteeIndex: committeeIndex,
AttesterSlot: aSlot,
ProposerSlot: pSlot,
Status: status,
Status: vs.assignmentStatus(idx, beaconState),
}, nil
}

View File

@@ -5,7 +5,6 @@ import (
"time"
ptypes "github.com/gogo/protobuf/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -54,7 +53,7 @@ type Server struct {
func (vs *Server) WaitForActivation(req *pb.ValidatorActivationRequest, stream pb.ValidatorService_WaitForActivationServer) error {
activeValidatorExists, validatorStatuses, err := vs.multipleValidatorStatus(stream.Context(), req.PublicKeys)
if err != nil {
return err
return status.Errorf(codes.Internal, "Could not fetch validator status: %v", err)
}
res := &pb.ValidatorActivationResponse{
Statuses: validatorStatuses,
@@ -63,7 +62,7 @@ func (vs *Server) WaitForActivation(req *pb.ValidatorActivationRequest, stream p
return stream.Send(res)
}
if err := stream.Send(res); err != nil {
return err
return status.Errorf(codes.Internal, "Could not send response over stream: %v", err)
}
for {
@@ -71,7 +70,7 @@ func (vs *Server) WaitForActivation(req *pb.ValidatorActivationRequest, stream p
case <-time.After(6 * time.Second):
activeValidatorExists, validatorStatuses, err := vs.multipleValidatorStatus(stream.Context(), req.PublicKeys)
if err != nil {
return err
return status.Errorf(codes.Internal, "Could not fetch validator status: %v", err)
}
res := &pb.ValidatorActivationResponse{
Statuses: validatorStatuses,
@@ -80,12 +79,12 @@ func (vs *Server) WaitForActivation(req *pb.ValidatorActivationRequest, stream p
return stream.Send(res)
}
if err := stream.Send(res); err != nil {
return err
return status.Errorf(codes.Internal, "Could not send response over stream: %v", err)
}
case <-stream.Context().Done():
return errors.New("stream context closed, exiting gorutine")
return status.Error(codes.Canceled, "Stream context canceled")
case <-vs.Ctx.Done():
return errors.New("rpc context closed, exiting goroutine")
return status.Error(codes.Canceled, "RPC context canceled")
}
}
}
@@ -94,10 +93,10 @@ func (vs *Server) WaitForActivation(req *pb.ValidatorActivationRequest, stream p
func (vs *Server) ValidatorIndex(ctx context.Context, req *pb.ValidatorIndexRequest) (*pb.ValidatorIndexResponse, error) {
index, ok, err := vs.BeaconDB.ValidatorIndex(ctx, bytesutil.ToBytes48(req.PublicKey))
if err != nil {
return nil, status.Errorf(codes.Internal, "could not retrieve validator index: %v", err)
return nil, status.Errorf(codes.Internal, "Could not fetch validator index: %v", err)
}
if !ok {
return nil, status.Errorf(codes.Internal, "could not find validator index for public key %#x not found", req.PublicKey)
return nil, status.Errorf(codes.Internal, "Could not find validator index for public key %#x not found", req.PublicKey)
}
return &pb.ValidatorIndexResponse{Index: index}, nil
@@ -114,7 +113,7 @@ func (vs *Server) ValidatorPerformance(
if req.Slot > headState.Slot {
headState, err = state.ProcessSlots(ctx, headState, req.Slot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to %d", req.Slot)
return nil, status.Errorf(codes.Internal, "Could not process slots up to %d: %v", req.Slot, err)
}
}
@@ -132,12 +131,12 @@ func (vs *Server) ValidatorPerformance(
activeCount, err := helpers.ActiveValidatorCount(headState, helpers.SlotToEpoch(req.Slot))
if err != nil {
return nil, errors.Wrap(err, "could not retrieve active validator count")
return nil, status.Errorf(codes.Internal, "Could not retrieve active validator count: %v", err)
}
totalActiveBalance, err := helpers.TotalActiveBalance(headState)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve active balance")
return nil, status.Errorf(codes.Internal, "Could not retrieve total active balance: %v", err)
}
avgBalance := float32(totalActiveBalance / activeCount)
@@ -158,16 +157,16 @@ func (vs *Server) ExitedValidators(
_, statuses, err := vs.multipleValidatorStatus(ctx, req.PublicKeys)
if err != nil {
return nil, err
return nil, status.Errorf(codes.Internal, "Could not retrieve validator statuses: %v", err)
}
exitedKeys := make([][]byte, 0)
for _, status := range statuses {
s := status.Status.Status
for _, st := range statuses {
s := st.Status.Status
if s == pb.ValidatorStatus_EXITED ||
s == pb.ValidatorStatus_EXITED_SLASHED ||
s == pb.ValidatorStatus_INITIATED_EXIT {
exitedKeys = append(exitedKeys, status.PublicKey)
exitedKeys = append(exitedKeys, st.PublicKey)
}
}
@@ -200,7 +199,7 @@ func (vs *Server) CanonicalHead(ctx context.Context, req *ptypes.Empty) (*ethpb.
func (vs *Server) WaitForChainStart(req *ptypes.Empty, stream pb.ValidatorService_WaitForChainStartServer) error {
head, err := vs.BeaconDB.HeadState(context.Background())
if err != nil {
return err
return status.Errorf(codes.Internal, "Could not retrieve head state: %v", err)
}
if head != nil {
res := &pb.ChainStartResponse{
@@ -222,9 +221,9 @@ func (vs *Server) WaitForChainStart(req *ptypes.Empty, stream pb.ValidatorServic
}
return stream.Send(res)
case <-sub.Err():
return errors.New("subscriber closed, exiting goroutine")
return status.Error(codes.Aborted, "Subscriber closed, exiting goroutine")
case <-vs.Ctx.Done():
return errors.New("rpc context closed, exiting goroutine")
return status.Error(codes.Canceled, "Context canceled")
}
}
}

View File

@@ -105,7 +105,7 @@ func TestWaitForActivation_ContextClosed(t *testing.T) {
mockChainStream.EXPECT().Context().Return(context.Background())
exitRoutine := make(chan bool)
go func(tt *testing.T) {
want := "context closed"
want := "context canceled"
if err := vs.WaitForActivation(req, mockChainStream); !strings.Contains(err.Error(), want) {
tt.Errorf("Could not call RPC method: %v", err)
}
@@ -249,7 +249,7 @@ func TestWaitForChainStart_ContextClosed(t *testing.T) {
defer ctrl.Finish()
mockStream := mockRPC.NewMockValidatorService_WaitForChainStartServer(ctrl)
go func(tt *testing.T) {
if err := Server.WaitForChainStart(&ptypes.Empty{}, mockStream); !strings.Contains(err.Error(), "context closed") {
if err := Server.WaitForChainStart(&ptypes.Empty{}, mockStream); !strings.Contains(err.Error(), "Context canceled") {
tt.Errorf("Could not call RPC method: %v", err)
}
<-exitRoutine

View File

@@ -60,6 +60,7 @@ func (vs *Server) multipleValidatorStatus(
return activeValidatorExists, statusResponses, nil
}
func (vs *Server) validatorStatus(ctx context.Context, pubKey []byte, headState *pbp2p.BeaconState) *pb.ValidatorStatusResponse {
if !vs.Eth1InfoFetcher.IsConnectedToETH1() {
vStatus, idx, err := vs.retrieveStatusFromState(ctx, pubKey, headState)
@@ -117,7 +118,7 @@ func (vs *Server) validatorStatus(ctx context.Context, pubKey []byte, headState
}
}
// Our position in the activation queue is the above index - our validator index.
queuePosition = uint64(idx) - lastActivatedValidatorIdx
queuePosition = idx - lastActivatedValidatorIdx
return &pb.ValidatorStatusResponse{
Status: vStatus,
Eth1DepositBlockNumber: eth1BlockNumBigInt.Uint64(),
@@ -139,7 +140,7 @@ func (vs *Server) retrieveStatusFromState(ctx context.Context, pubKey []byte,
if !ok {
return pb.ValidatorStatus(0), 0, errors.New("pubkey does not exist")
}
return vs.assignmentStatus(uint64(idx), headState), uint64(idx), nil
return vs.assignmentStatus(idx, headState), idx, nil
}
func (vs *Server) assignmentStatus(validatorIdx uint64, beaconState *pbp2p.BeaconState) pb.ValidatorStatus {