package beaconv1 import ( "context" "errors" "fmt" "reflect" "strconv" "strings" "github.com/ethereum/go-ethereum/common/hexutil" ptypes "github.com/gogo/protobuf/types" ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1" "github.com/prysmaticlabs/prysm/shared/params" "go.opencensus.io/trace" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // GetForkSchedule retrieve all scheduled upcoming forks this node is aware of. func (bs *Server) GetForkSchedule(ctx context.Context, req *ptypes.Empty) (*ethpb.ForkScheduleResponse, error) { return nil, errors.New("unimplemented") } // GetSpec retrieves specification configuration (without Phase 1 params) used on this node. Specification params list // Values are returned with following format: // - any value starting with 0x in the spec is returned as a hex string. // - all other values are returned as number. func (bs *Server) GetSpec(ctx context.Context, _ *ptypes.Empty) (*ethpb.SpecResponse, error) { ctx, span := trace.StartSpan(ctx, "beaconV1.GetSpec") defer span.End() data, err := prepareConfigSpec() if err != nil { return nil, status.Errorf(codes.Internal, "Failed to prepare spec data: %v", err) } return ðpb.SpecResponse{Data: data}, nil } // GetDepositContract retrieves deposit contract address and genesis fork version. func (bs *Server) GetDepositContract(ctx context.Context, req *ptypes.Empty) (*ethpb.DepositContractResponse, error) { ctx, span := trace.StartSpan(ctx, "beaconv1.GetDepositContract") defer span.End() return ðpb.DepositContractResponse{ Data: ðpb.DepositContract{ ChainId: params.BeaconConfig().DepositChainID, Address: params.BeaconConfig().DepositContractAddress, }, }, nil } func prepareConfigSpec() (map[string]string, error) { data := make(map[string]string) config := *params.BeaconConfig() t := reflect.TypeOf(config) v := reflect.ValueOf(config) for i := 0; i < t.NumField(); i++ { tField := t.Field(i) _, isSpecField := tField.Tag.Lookup("spec") if !isSpecField { // Field should not be returned from API. continue } tagValue := strings.ToLower(tField.Tag.Get("yaml")) vField := v.Field(i) switch vField.Kind() { case reflect.Uint64: data[tagValue] = strconv.FormatUint(vField.Uint(), 10) case reflect.Slice: data[tagValue] = hexutil.Encode(vField.Bytes()) case reflect.Array: data[tagValue] = hexutil.Encode(reflect.ValueOf(&config).Elem().Field(i).Slice(0, vField.Len()).Bytes()) case reflect.String: data[tagValue] = vField.String() case reflect.Uint8: data[tagValue] = hexutil.Encode([]byte{uint8(vField.Uint())}) default: return nil, fmt.Errorf("unsupported config field type: %s", vField.Kind().String()) } } return data, nil }