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 ðpb.GenesisResponse{ 35 Data: ðpb.GenesisResponse_Genesis{ 36 GenesisTime: ×tamppb.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 ðpb.StateRootResponse{ 67 Data: ðpb.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 ðpb.StateForkResponse{ 95 Data: ðpb.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 ðpb.StateFinalityCheckpointResponse{ 125 Data: ðpb.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 ðpb.Checkpoint{ 136 Epoch: sourceCheckpoint.Epoch, 137 Root: sourceCheckpoint.Root, 138 } 139 } 140 return ðpb.Checkpoint{ 141 Epoch: 0, 142 Root: params.BeaconConfig().ZeroHash[:], 143 } 144 }