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 &ethpb.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] = &ethpb.Fork{
    44  			PreviousVersion: previous,
    45  			CurrentVersion:  current,
    46  			Epoch:           e,
    47  		}
    48  	}
    49  
    50  	return &ethpb.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 &ethpb.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 &ethpb.DepositContractResponse{
    76  		Data: &ethpb.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  }