github.com/prysmaticlabs/prysm@v1.4.4/slasher/beaconclient/chain_data.go (about)

     1  package beaconclient
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"github.com/pkg/errors"
     8  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
     9  	"github.com/prysmaticlabs/prysm/shared/params"
    10  	"go.opencensus.io/trace"
    11  	"google.golang.org/protobuf/types/known/emptypb"
    12  )
    13  
    14  var syncStatusPollingInterval = time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second
    15  
    16  // ChainHead requests the latest beacon chain head
    17  // from a beacon node via gRPC.
    18  func (s *Service) ChainHead(
    19  	ctx context.Context,
    20  ) (*ethpb.ChainHead, error) {
    21  	ctx, span := trace.StartSpan(ctx, "beaconclient.ChainHead")
    22  	defer span.End()
    23  	res, err := s.cfg.BeaconClient.GetChainHead(ctx, &emptypb.Empty{})
    24  	if err != nil || res == nil {
    25  		return nil, errors.Wrap(err, "Could not retrieve chain head or got nil chain head")
    26  	}
    27  	return res, nil
    28  }
    29  
    30  // GenesisValidatorsRoot requests or fetch from memory the beacon chain genesis
    31  // validators root via gRPC.
    32  func (s *Service) GenesisValidatorsRoot(
    33  	ctx context.Context,
    34  ) ([]byte, error) {
    35  	ctx, span := trace.StartSpan(ctx, "beaconclient.GenesisValidatorsRoot")
    36  	defer span.End()
    37  
    38  	if s.genesisValidatorRoot == nil {
    39  		res, err := s.cfg.NodeClient.GetGenesis(ctx, &emptypb.Empty{})
    40  		if err != nil {
    41  			return nil, errors.Wrap(err, "could not retrieve genesis data")
    42  		}
    43  		if res == nil {
    44  			return nil, errors.Wrap(err, "nil genesis data")
    45  		}
    46  		s.genesisValidatorRoot = res.GenesisValidatorsRoot
    47  	}
    48  	return s.genesisValidatorRoot, nil
    49  }
    50  
    51  // Poll the beacon node every syncStatusPollingInterval until the node
    52  // is no longer syncing.
    53  func (s *Service) querySyncStatus(ctx context.Context) {
    54  	status, err := s.cfg.NodeClient.GetSyncStatus(ctx, &emptypb.Empty{})
    55  	if err != nil {
    56  		log.WithError(err).Error("Could not fetch sync status")
    57  	}
    58  	if status != nil && !status.Syncing {
    59  		log.Info("Beacon node is fully synced, starting slashing detection")
    60  		return
    61  	}
    62  	ticker := time.NewTicker(syncStatusPollingInterval)
    63  	defer ticker.Stop()
    64  	log.Info("Waiting for beacon node to be fully synced...")
    65  	for {
    66  		select {
    67  		case <-ticker.C:
    68  			status, err := s.cfg.NodeClient.GetSyncStatus(ctx, &emptypb.Empty{})
    69  			if err != nil {
    70  				log.WithError(err).Error("Could not fetch sync status")
    71  			}
    72  			if status != nil && !status.Syncing {
    73  				log.Info("Beacon node is fully synced, starting slashing detection")
    74  				return
    75  			}
    76  			log.Info("Waiting for beacon node to be fully synced...")
    77  		case <-ctx.Done():
    78  			log.Debug("Context closed, exiting routine")
    79  			return
    80  		}
    81  	}
    82  }