github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/rpc/eth/v1/beacon/state.go (about)

     1  package beacon
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  
     7  	"github.com/prysmaticlabs/prysm/beacon-chain/rpc/statefetcher"
     8  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
     9  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1"
    10  	eth "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    11  	"github.com/prysmaticlabs/prysm/shared/params"
    12  	"go.opencensus.io/trace"
    13  	"google.golang.org/grpc/codes"
    14  	"google.golang.org/grpc/status"
    15  	"google.golang.org/protobuf/types/known/emptypb"
    16  	"google.golang.org/protobuf/types/known/timestamppb"
    17  )
    18  
    19  // GetGenesis retrieves details of the chain's genesis which can be used to identify chain.
    20  func (bs *Server) GetGenesis(ctx context.Context, _ *emptypb.Empty) (*ethpb.GenesisResponse, error) {
    21  	ctx, span := trace.StartSpan(ctx, "beaconv1.GetGenesis")
    22  	defer span.End()
    23  
    24  	genesisTime := bs.GenesisTimeFetcher.GenesisTime()
    25  	if genesisTime.IsZero() {
    26  		return nil, status.Errorf(codes.NotFound, "Chain genesis info is not yet known")
    27  	}
    28  	validatorRoot := bs.ChainInfoFetcher.GenesisValidatorRoot()
    29  	if bytes.Equal(validatorRoot[:], params.BeaconConfig().ZeroHash[:]) {
    30  		return nil, status.Errorf(codes.NotFound, "Chain genesis info is not yet known")
    31  	}
    32  	forkVersion := params.BeaconConfig().GenesisForkVersion
    33  
    34  	return &ethpb.GenesisResponse{
    35  		Data: &ethpb.GenesisResponse_Genesis{
    36  			GenesisTime: &timestamppb.Timestamp{
    37  				Seconds: genesisTime.Unix(),
    38  				Nanos:   0,
    39  			},
    40  			GenesisValidatorsRoot: validatorRoot[:],
    41  			GenesisForkVersion:    forkVersion,
    42  		},
    43  	}, nil
    44  }
    45  
    46  // GetStateRoot calculates HashTreeRoot for state with given 'stateId'. If stateId is root, same value will be returned.
    47  func (bs *Server) GetStateRoot(ctx context.Context, req *ethpb.StateRequest) (*ethpb.StateRootResponse, error) {
    48  	ctx, span := trace.StartSpan(ctx, "beaconv1.GetStateRoot")
    49  	defer span.End()
    50  
    51  	var (
    52  		root []byte
    53  		err  error
    54  	)
    55  
    56  	root, err = bs.StateFetcher.StateRoot(ctx, req.StateId)
    57  	if err != nil {
    58  		if rootNotFoundErr, ok := err.(*statefetcher.StateRootNotFoundError); ok {
    59  			return nil, status.Errorf(codes.NotFound, "State root not found: %v", rootNotFoundErr)
    60  		} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
    61  			return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
    62  		}
    63  		return nil, status.Errorf(codes.Internal, "Could not get state root: %v", err)
    64  	}
    65  
    66  	return &ethpb.StateRootResponse{
    67  		Data: &ethpb.StateRootResponse_StateRoot{
    68  			Root: root,
    69  		},
    70  	}, nil
    71  }
    72  
    73  // GetStateFork returns Fork object for state with given 'stateId'.
    74  func (bs *Server) GetStateFork(ctx context.Context, req *ethpb.StateRequest) (*ethpb.StateForkResponse, error) {
    75  	ctx, span := trace.StartSpan(ctx, "beaconv1.GetStateFork")
    76  	defer span.End()
    77  
    78  	var (
    79  		state iface.BeaconState
    80  		err   error
    81  	)
    82  
    83  	state, err = bs.StateFetcher.State(ctx, req.StateId)
    84  	if err != nil {
    85  		if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
    86  			return nil, status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
    87  		} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
    88  			return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
    89  		}
    90  		return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
    91  	}
    92  
    93  	fork := state.Fork()
    94  	return &ethpb.StateForkResponse{
    95  		Data: &ethpb.Fork{
    96  			PreviousVersion: fork.PreviousVersion,
    97  			CurrentVersion:  fork.CurrentVersion,
    98  			Epoch:           fork.Epoch,
    99  		},
   100  	}, nil
   101  }
   102  
   103  // GetFinalityCheckpoints returns finality checkpoints for state with given 'stateId'. In case finality is
   104  // not yet achieved, checkpoint should return epoch 0 and ZERO_HASH as root.
   105  func (bs *Server) GetFinalityCheckpoints(ctx context.Context, req *ethpb.StateRequest) (*ethpb.StateFinalityCheckpointResponse, error) {
   106  	ctx, span := trace.StartSpan(ctx, "beaconv1.GetFinalityCheckpoints")
   107  	defer span.End()
   108  
   109  	var (
   110  		state iface.BeaconState
   111  		err   error
   112  	)
   113  
   114  	state, err = bs.StateFetcher.State(ctx, req.StateId)
   115  	if err != nil {
   116  		if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
   117  			return nil, status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
   118  		} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
   119  			return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
   120  		}
   121  		return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
   122  	}
   123  
   124  	return &ethpb.StateFinalityCheckpointResponse{
   125  		Data: &ethpb.StateFinalityCheckpointResponse_StateFinalityCheckpoint{
   126  			PreviousJustified: checkpoint(state.PreviousJustifiedCheckpoint()),
   127  			CurrentJustified:  checkpoint(state.CurrentJustifiedCheckpoint()),
   128  			Finalized:         checkpoint(state.FinalizedCheckpoint()),
   129  		},
   130  	}, nil
   131  }
   132  
   133  func checkpoint(sourceCheckpoint *eth.Checkpoint) *ethpb.Checkpoint {
   134  	if sourceCheckpoint != nil {
   135  		return &ethpb.Checkpoint{
   136  			Epoch: sourceCheckpoint.Epoch,
   137  			Root:  sourceCheckpoint.Root,
   138  		}
   139  	}
   140  	return &ethpb.Checkpoint{
   141  		Epoch: 0,
   142  		Root:  params.BeaconConfig().ZeroHash[:],
   143  	}
   144  }