github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/rpc/eth/v1/beacon/config.go (about) 1 package beacon 2 3 import ( 4 "context" 5 "fmt" 6 "reflect" 7 "sort" 8 "strconv" 9 "strings" 10 11 "github.com/ethereum/go-ethereum/common/hexutil" 12 types "github.com/prysmaticlabs/eth2-types" 13 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1" 14 "github.com/prysmaticlabs/prysm/shared/params" 15 "go.opencensus.io/trace" 16 "google.golang.org/grpc/codes" 17 "google.golang.org/grpc/status" 18 "google.golang.org/protobuf/types/known/emptypb" 19 ) 20 21 // GetForkSchedule retrieve all scheduled upcoming forks this node is aware of. 22 func (bs *Server) GetForkSchedule(ctx context.Context, _ *emptypb.Empty) (*ethpb.ForkScheduleResponse, error) { 23 ctx, span := trace.StartSpan(ctx, "beaconv1.GetForkSchedule") 24 defer span.End() 25 26 schedule := params.BeaconConfig().ForkVersionSchedule 27 if len(schedule) == 0 { 28 return ðpb.ForkScheduleResponse{ 29 Data: make([]*ethpb.Fork, 0), 30 }, nil 31 } 32 33 epochs := sortedEpochs(schedule) 34 forks := make([]*ethpb.Fork, len(schedule)) 35 var previous, current []byte 36 for i, e := range epochs { 37 if i == 0 { 38 previous = params.BeaconConfig().GenesisForkVersion 39 } else { 40 previous = current 41 } 42 current = schedule[e] 43 forks[i] = ðpb.Fork{ 44 PreviousVersion: previous, 45 CurrentVersion: current, 46 Epoch: e, 47 } 48 } 49 50 return ðpb.ForkScheduleResponse{ 51 Data: forks, 52 }, nil 53 } 54 55 // GetSpec retrieves specification configuration (without Phase 1 params) used on this node. Specification params list 56 // Values are returned with following format: 57 // - any value starting with 0x in the spec is returned as a hex string. 58 // - all other values are returned as number. 59 func (bs *Server) GetSpec(ctx context.Context, _ *emptypb.Empty) (*ethpb.SpecResponse, error) { 60 ctx, span := trace.StartSpan(ctx, "beaconV1.GetSpec") 61 defer span.End() 62 63 data, err := prepareConfigSpec() 64 if err != nil { 65 return nil, status.Errorf(codes.Internal, "Failed to prepare spec data: %v", err) 66 } 67 return ðpb.SpecResponse{Data: data}, nil 68 } 69 70 // GetDepositContract retrieves deposit contract address and genesis fork version. 71 func (bs *Server) GetDepositContract(ctx context.Context, _ *emptypb.Empty) (*ethpb.DepositContractResponse, error) { 72 ctx, span := trace.StartSpan(ctx, "beaconv1.GetDepositContract") 73 defer span.End() 74 75 return ðpb.DepositContractResponse{ 76 Data: ðpb.DepositContract{ 77 ChainId: params.BeaconConfig().DepositChainID, 78 Address: params.BeaconConfig().DepositContractAddress, 79 }, 80 }, nil 81 } 82 83 func sortedEpochs(forkSchedule map[types.Epoch][]byte) []types.Epoch { 84 sortedEpochs := make([]types.Epoch, len(forkSchedule)) 85 i := 0 86 for k := range forkSchedule { 87 sortedEpochs[i] = k 88 i++ 89 } 90 sort.Slice(sortedEpochs, func(a, b int) bool { return sortedEpochs[a] < sortedEpochs[b] }) 91 return sortedEpochs 92 } 93 94 func prepareConfigSpec() (map[string]string, error) { 95 data := make(map[string]string) 96 config := *params.BeaconConfig() 97 t := reflect.TypeOf(config) 98 v := reflect.ValueOf(config) 99 100 for i := 0; i < t.NumField(); i++ { 101 tField := t.Field(i) 102 _, isSpecField := tField.Tag.Lookup("spec") 103 if !isSpecField { 104 // Field should not be returned from API. 105 continue 106 } 107 108 tagValue := strings.ToUpper(tField.Tag.Get("yaml")) 109 vField := v.Field(i) 110 switch vField.Kind() { 111 case reflect.Uint64: 112 data[tagValue] = strconv.FormatUint(vField.Uint(), 10) 113 case reflect.Slice: 114 data[tagValue] = hexutil.Encode(vField.Bytes()) 115 case reflect.Array: 116 data[tagValue] = hexutil.Encode(reflect.ValueOf(&config).Elem().Field(i).Slice(0, vField.Len()).Bytes()) 117 case reflect.String: 118 data[tagValue] = vField.String() 119 case reflect.Uint8: 120 data[tagValue] = hexutil.Encode([]byte{uint8(vField.Uint())}) 121 default: 122 return nil, fmt.Errorf("unsupported config field type: %s", vField.Kind().String()) 123 } 124 } 125 126 return data, nil 127 }