prysm-pulse/beacon-chain/rpc/eth/config/handlers.go
Radosław Kapka 4c47756aed
HTTP endpoints cleanup (#13251)
* remove validation package

* structs cleanup

* merge with apimiddleware removal

* more validation and Bls capitalization

* builder test fix

* use strconv for uint->str conversions

* use DecodeHexWithLength

* use exact param names

* rename http package to httputil

* change conversions to fmt.Sprintf

* handle query paramsd and route variables

* spans and receiver name

* split structs, move bytes helper

* missing ok check

* fix reference to indexed failure

* errors fixup

* add godoc to helper

* fix BLS casing and chainhead ref

* review

* fix import in tests

* gzl
2023-12-08 20:37:20 +00:00

119 lines
3.5 KiB
Go

package config
import (
"fmt"
"net/http"
"reflect"
"strconv"
"strings"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/network/forks"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
"go.opencensus.io/trace"
)
// GetDepositContract retrieves deposit contract address and genesis fork version.
func GetDepositContract(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "config.GetDepositContract")
defer span.End()
httputil.WriteJson(w, &GetDepositContractResponse{
Data: &DepositContractData{
ChainId: strconv.FormatUint(params.BeaconConfig().DepositChainID, 10),
Address: params.BeaconConfig().DepositContractAddress,
},
})
}
// GetForkSchedule retrieve all scheduled upcoming forks this node is aware of.
func GetForkSchedule(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "config.GetForkSchedule")
defer span.End()
schedule := params.BeaconConfig().ForkVersionSchedule
if len(schedule) == 0 {
httputil.WriteJson(w, &GetForkScheduleResponse{
Data: make([]*shared.Fork, 0),
})
return
}
versions := forks.SortedForkVersions(schedule)
chainForks := make([]*shared.Fork, len(schedule))
var previous, current []byte
for i, v := range versions {
if i == 0 {
previous = params.BeaconConfig().GenesisForkVersion
} else {
previous = current
}
copyV := v
current = copyV[:]
chainForks[i] = &shared.Fork{
PreviousVersion: hexutil.Encode(previous),
CurrentVersion: hexutil.Encode(current),
Epoch: fmt.Sprintf("%d", schedule[v]),
}
}
httputil.WriteJson(w, &GetForkScheduleResponse{
Data: chainForks,
})
}
// 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 GetSpec(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "config.GetSpec")
defer span.End()
data, err := prepareConfigSpec()
if err != nil {
httputil.HandleError(w, "Could not prepare config spec: "+err.Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, &GetSpecResponse{Data: data})
}
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.ToUpper(tField.Tag.Get("yaml"))
vField := v.Field(i)
switch vField.Kind() {
case reflect.Int:
data[tagValue] = strconv.FormatInt(vField.Int(), 10)
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
}