github.com/prysmaticlabs/prysm@v1.4.4/validator/rpc/health.go (about)

     1  package rpc
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"github.com/pkg/errors"
     8  	pb "github.com/prysmaticlabs/prysm/proto/validator/accounts/v2"
     9  	"github.com/prysmaticlabs/prysm/shared/version"
    10  	"google.golang.org/grpc/codes"
    11  	"google.golang.org/grpc/status"
    12  	"google.golang.org/protobuf/types/known/emptypb"
    13  )
    14  
    15  // GetBeaconNodeConnection retrieves the current beacon node connection
    16  // information, as well as its sync status.
    17  func (s *Server) GetBeaconNodeConnection(ctx context.Context, _ *emptypb.Empty) (*pb.NodeConnectionResponse, error) {
    18  	syncStatus, err := s.syncChecker.Syncing(ctx)
    19  	if err != nil || s.validatorService.Status() != nil {
    20  		return &pb.NodeConnectionResponse{
    21  			GenesisTime:        0,
    22  			BeaconNodeEndpoint: s.nodeGatewayEndpoint,
    23  			Connected:          false,
    24  			Syncing:            false,
    25  		}, nil
    26  	}
    27  	genesis, err := s.genesisFetcher.GenesisInfo(ctx)
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  	return &pb.NodeConnectionResponse{
    32  		GenesisTime:            uint64(time.Unix(genesis.GenesisTime.Seconds, 0).Unix()),
    33  		DepositContractAddress: genesis.DepositContractAddress,
    34  		BeaconNodeEndpoint:     s.nodeGatewayEndpoint,
    35  		Connected:              true,
    36  		Syncing:                syncStatus,
    37  	}, nil
    38  }
    39  
    40  // GetLogsEndpoints for the beacon and validator client.
    41  func (s *Server) GetLogsEndpoints(ctx context.Context, _ *emptypb.Empty) (*pb.LogsEndpointResponse, error) {
    42  	return nil, status.Error(codes.Unimplemented, "unimplemented")
    43  }
    44  
    45  // GetVersion --
    46  func (s *Server) GetVersion(ctx context.Context, _ *emptypb.Empty) (*pb.VersionResponse, error) {
    47  	beacon, err := s.beaconNodeClient.GetVersion(ctx, &emptypb.Empty{})
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	return &pb.VersionResponse{
    53  		Beacon:    beacon.Version,
    54  		Validator: version.Version(),
    55  	}, nil
    56  }
    57  
    58  // StreamBeaconLogs from the beacon node via a gRPC server-side stream.
    59  func (s *Server) StreamBeaconLogs(req *emptypb.Empty, stream pb.Health_StreamBeaconLogsServer) error {
    60  	// Wrap service context with a cancel in order to propagate the exiting of
    61  	// this method properly to the beacon node server.
    62  	ctx, cancel := context.WithCancel(s.ctx)
    63  	defer cancel()
    64  
    65  	client, err := s.beaconNodeHealthClient.StreamBeaconLogs(ctx, req)
    66  	if err != nil {
    67  		return err
    68  	}
    69  	for {
    70  		select {
    71  		case <-s.ctx.Done():
    72  			return status.Error(codes.Canceled, "Context canceled")
    73  		case <-stream.Context().Done():
    74  			return status.Error(codes.Canceled, "Context canceled")
    75  		case <-client.Context().Done():
    76  			return status.Error(codes.Canceled, "Context canceled")
    77  		default:
    78  			resp, err := client.Recv()
    79  			if err != nil {
    80  				return errors.Wrap(err, "could not receive beacon logs from stream")
    81  			}
    82  			if err := stream.Send(resp); err != nil {
    83  				return status.Errorf(codes.Unavailable, "Could not send over stream: %v", err)
    84  			}
    85  		}
    86  	}
    87  }
    88  
    89  // StreamValidatorLogs from the validator client via a gRPC server-side stream.
    90  func (s *Server) StreamValidatorLogs(_ *emptypb.Empty, stream pb.Health_StreamValidatorLogsServer) error {
    91  	ch := make(chan []byte, s.streamLogsBufferSize)
    92  	sub := s.logsStreamer.LogsFeed().Subscribe(ch)
    93  	defer func() {
    94  		sub.Unsubscribe()
    95  		defer close(ch)
    96  	}()
    97  
    98  	recentLogs := s.logsStreamer.GetLastFewLogs()
    99  	logStrings := make([]string, len(recentLogs))
   100  	for i, log := range recentLogs {
   101  		logStrings[i] = string(log)
   102  	}
   103  	if err := stream.Send(&pb.LogsResponse{
   104  		Logs: logStrings,
   105  	}); err != nil {
   106  		return status.Errorf(codes.Unavailable, "Could not send over stream: %v", err)
   107  	}
   108  	for {
   109  		select {
   110  		case log := <-ch:
   111  			resp := &pb.LogsResponse{
   112  				Logs: []string{string(log)},
   113  			}
   114  			if err := stream.Send(resp); err != nil {
   115  				return status.Errorf(codes.Unavailable, "Could not send over stream: %v", err)
   116  			}
   117  		case <-s.ctx.Done():
   118  			return status.Error(codes.Canceled, "Context canceled")
   119  		case err := <-sub.Err():
   120  			return status.Errorf(codes.Canceled, "Subscriber error, closing: %v", err)
   121  		case <-stream.Context().Done():
   122  			return status.Error(codes.Canceled, "Context canceled")
   123  		}
   124  	}
   125  }