Skip to content

Commit

Permalink
more endpoints (#9109)
Browse files Browse the repository at this point in the history
  • Loading branch information
elee1766 authored Jan 1, 2024
1 parent a959387 commit bab123c
Show file tree
Hide file tree
Showing 23 changed files with 762 additions and 131 deletions.
39 changes: 27 additions & 12 deletions cl/beacon/beaconhttp/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ func (e *EndpointError) WriteTo(w http.ResponseWriter) {
}

type EndpointHandler[T any] interface {
Handle(r *http.Request) (T, error)
Handle(w http.ResponseWriter, r *http.Request) (T, error)
}

type EndpointHandlerFunc[T any] func(r *http.Request) (T, error)
type EndpointHandlerFunc[T any] func(w http.ResponseWriter, r *http.Request) (T, error)

func (e EndpointHandlerFunc[T]) Handle(r *http.Request) (T, error) {
return e(r)
func (e EndpointHandlerFunc[T]) Handle(w http.ResponseWriter, r *http.Request) (T, error) {
return e(w, r)
}

func HandleEndpointFunc[T any](h EndpointHandlerFunc[T]) http.HandlerFunc {
Expand All @@ -70,7 +70,7 @@ func HandleEndpointFunc[T any](h EndpointHandlerFunc[T]) http.HandlerFunc {
func HandleEndpoint[T any](h EndpointHandler[T]) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
ans, err := h.Handle(r)
ans, err := h.Handle(w, r)
log.Debug("beacon api request", "endpoint", r.URL.Path, "duration", time.Since(start))
if err != nil {
log.Error("beacon api request error", "err", err)
Expand All @@ -83,7 +83,6 @@ func HandleEndpoint[T any](h EndpointHandler[T]) http.HandlerFunc {
endpointError.WriteTo(w)
return
}
// TODO: ssz handler
// TODO: potentially add a context option to buffer these
contentType := r.Header.Get("Accept")
contentTypes := strings.Split(contentType, ",")
Expand All @@ -102,15 +101,31 @@ func HandleEndpoint[T any](h EndpointHandler[T]) http.HandlerFunc {
}
w.Write(encoded)
case contentType == "*/*", contentType == "", slices.Contains(contentTypes, "text/html"), slices.Contains(contentTypes, "application/json"):
w.Header().Add("content-type", "application/json")
err := json.NewEncoder(w).Encode(ans)
if err != nil {
// this error is fatal, log to console
log.Error("beaconapi failed to encode json", "type", reflect.TypeOf(ans), "err", err)
if !isNil(ans) {
w.Header().Add("content-type", "application/json")
err := json.NewEncoder(w).Encode(ans)
if err != nil {
// this error is fatal, log to console
log.Error("beaconapi failed to encode json", "type", reflect.TypeOf(ans), "err", err)
}
} else {
w.WriteHeader(200)
}
default:
http.Error(w, "content type must be application/json or application/octet-stream", http.StatusBadRequest)

}
})
}

func isNil[T any](t T) bool {
v := reflect.ValueOf(t)
kind := v.Kind()
// Must be one of these types to be nillable
return (kind == reflect.Ptr ||
kind == reflect.Interface ||
kind == reflect.Slice ||
kind == reflect.Map ||
kind == reflect.Chan ||
kind == reflect.Func) &&
v.IsNil()
}
28 changes: 28 additions & 0 deletions cl/beacon/beaconhttp/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package beaconhttp

import (
"encoding/json"
"strconv"
)

type IntStr int

func (i IntStr) MarshalJSON() ([]byte, error) {
return json.Marshal(strconv.FormatInt(int64(i), 10))
}

func (i *IntStr) UnmarshalJSON(b []byte) error {
// Try string first
var s string
if err := json.Unmarshal(b, &s); err == nil {
value, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return err
}
*i = IntStr(value)
return nil
}

// Fallback to number
return json.Unmarshal(b, (*int)(i))
}
25 changes: 25 additions & 0 deletions cl/beacon/building/endpoints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package building

import (
"github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon/cl/beacon/beaconhttp"
)

type BeaconCommitteeSubscription struct {
ValidatorIndex int `json:"validator_index,string"`
CommitteeIndex int `json:"committee_index,string"`
CommitteesAtSlot int `json:"committees_at_slot,string"`
Slot int `json:"slot,string"`
IsAggregator bool `json:"is_aggregator"`
}

type SyncCommitteeSubscription struct {
ValidatorIndex int `json:"validator_index,string"`
SyncCommitteeIndices []beaconhttp.IntStr `json:"sync_committee_indices"`
UntilEpoch int `json:"until_epoch,string"`
}

type PrepareBeaconProposer struct {
ValidatorIndex int `json:"validator_index,string"`
FeeRecipient common.Address `json:"fee_recipient"`
}
25 changes: 25 additions & 0 deletions cl/beacon/building/state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package building

import (
"sync"

"github.com/ledgerwatch/erigon-lib/common"
)

type State struct {
feeRecipients map[int]common.Address

mu sync.RWMutex
}

func NewState() *State {
return &State{
feeRecipients: map[int]common.Address{},
}
}

func (s *State) SetFeeRecipient(idx int, address common.Address) {
s.mu.Lock()
defer s.mu.Unlock()
s.feeRecipients[idx] = address
}
2 changes: 1 addition & 1 deletion cl/beacon/handler/attestation_rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type attestationsRewardsResponse struct {
TotalRewards []TotalReward `json:"total_rewards"`
}

func (a *ApiHandler) getAttestationsRewards(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getAttestationsRewards(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

tx, err := a.indiciesDB.BeginRo(ctx)
Expand Down
8 changes: 4 additions & 4 deletions cl/beacon/handler/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (a *ApiHandler) rootFromBlockId(ctx context.Context, tx kv.Tx, blockId *seg
return
}

func (a *ApiHandler) getBlock(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getBlock(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()
tx, err := a.indiciesDB.BeginRo(ctx)
if err != nil {
Expand Down Expand Up @@ -94,7 +94,7 @@ func (a *ApiHandler) getBlock(r *http.Request) (*beaconResponse, error) {
withVersion(blk.Version()), nil
}

func (a *ApiHandler) getBlindedBlock(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getBlindedBlock(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()
tx, err := a.indiciesDB.BeginRo(ctx)
if err != nil {
Expand Down Expand Up @@ -133,7 +133,7 @@ func (a *ApiHandler) getBlindedBlock(r *http.Request) (*beaconResponse, error) {
withVersion(blk.Version()), nil
}

func (a *ApiHandler) getBlockAttestations(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getBlockAttestations(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()
tx, err := a.indiciesDB.BeginRo(ctx)
if err != nil {
Expand Down Expand Up @@ -164,7 +164,7 @@ func (a *ApiHandler) getBlockAttestations(r *http.Request) (*beaconResponse, err
withVersion(blk.Version()), nil
}

func (a *ApiHandler) getBlockRoot(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getBlockRoot(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()
tx, err := a.indiciesDB.BeginRo(ctx)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cl/beacon/handler/committees.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type committeeResponse struct {
Validators []string `json:"validators"` // do string directly but it is still a base10 number
}

func (a *ApiHandler) getCommittees(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getCommittees(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

epochReq, err := uint64FromQueryParams(r, "epoch")
Expand Down
6 changes: 3 additions & 3 deletions cl/beacon/handler/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ import (
"github.com/ledgerwatch/erigon/cl/cltypes"
)

func (a *ApiHandler) getSpec(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getSpec(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
return newBeaconResponse(a.beaconChainCfg), nil
}

func (a *ApiHandler) getDepositContract(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getDepositContract(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
return newBeaconResponse(struct {
ChainId uint64 `json:"chain_id,string"`
DepositContract string `json:"address"`
}{ChainId: a.beaconChainCfg.DepositChainID, DepositContract: a.beaconChainCfg.DepositContractAddress}), nil

}

func (a *ApiHandler) getForkSchedule(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getForkSchedule(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
response := []cltypes.Fork{}
// create first response (unordered and incomplete)
for currentVersion, epoch := range a.beaconChainCfg.ForkVersionSchedule {
Expand Down
2 changes: 1 addition & 1 deletion cl/beacon/handler/duties_proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type proposerDuties struct {
Slot uint64 `json:"slot,string"`
}

func (a *ApiHandler) getDutiesProposer(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getDutiesProposer(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
epoch, err := epochFromRequest(r)
if err != nil {
return nil, beaconhttp.NewEndpointError(http.StatusBadRequest, err.Error())
Expand Down
2 changes: 1 addition & 1 deletion cl/beacon/handler/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type genesisResponse struct {
GenesisForkVersion libcommon.Bytes4 `json:"genesis_fork_version,omitempty"`
}

func (a *ApiHandler) getGenesis(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getGenesis(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
if a.genesisCfg == nil {
return nil, beaconhttp.NewEndpointError(http.StatusNotFound, "Genesis Config is missing")
}
Expand Down
4 changes: 2 additions & 2 deletions cl/beacon/handler/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/ledgerwatch/erigon/cl/persistence/beacon_indicies"
)

func (a *ApiHandler) getHeaders(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getHeaders(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

querySlot, err := uint64FromQueryParams(r, "slot")
Expand Down Expand Up @@ -89,7 +89,7 @@ func (a *ApiHandler) getHeaders(r *http.Request) (*beaconResponse, error) {
return newBeaconResponse(headers), nil
}

func (a *ApiHandler) getHeader(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getHeader(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()
tx, err := a.indiciesDB.BeginRo(ctx)
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions cl/beacon/handler/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ import (
"net/http"
)

func (a *ApiHandler) poolVoluntaryExits(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) poolVoluntaryExits(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
return newBeaconResponse(a.operationsPool.VoluntaryExistsPool.Raw()), nil
}

func (a *ApiHandler) poolAttesterSlashings(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) poolAttesterSlashings(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
return newBeaconResponse(a.operationsPool.AttesterSlashingsPool.Raw()), nil
}

func (a *ApiHandler) poolProposerSlashings(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) poolProposerSlashings(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
return newBeaconResponse(a.operationsPool.ProposerSlashingsPool.Raw()), nil
}

func (a *ApiHandler) poolBlsToExecutionChanges(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) poolBlsToExecutionChanges(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
return newBeaconResponse(a.operationsPool.BLSToExecutionChangesPool.Raw()), nil
}

func (a *ApiHandler) poolAttestations(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) poolAttestations(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
return newBeaconResponse(a.operationsPool.AttestationsPool.Raw()), nil
}
4 changes: 2 additions & 2 deletions cl/beacon/handler/rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type blockRewardsResponse struct {
Total uint64 `json:"total,string"`
}

func (a *ApiHandler) getBlockRewards(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getBlockRewards(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()
tx, err := a.indiciesDB.BeginRo(ctx)
if err != nil {
Expand Down Expand Up @@ -84,7 +84,7 @@ type syncCommitteeReward struct {
Reward int64 `json:"reward,string"`
}

func (a *ApiHandler) getSyncCommitteesRewards(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getSyncCommitteesRewards(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

tx, err := a.indiciesDB.BeginRo(ctx)
Expand Down
10 changes: 5 additions & 5 deletions cl/beacon/handler/states.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func previousVersion(v clparams.StateVersion) clparams.StateVersion {
return v - 1
}

func (a *ApiHandler) getStateFork(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getStateFork(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

tx, err := a.indiciesDB.BeginRo(ctx)
Expand Down Expand Up @@ -110,7 +110,7 @@ func (a *ApiHandler) getStateFork(r *http.Request) (*beaconResponse, error) {
}), nil
}

func (a *ApiHandler) getStateRoot(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getStateRoot(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

tx, err := a.indiciesDB.BeginRo(ctx)
Expand Down Expand Up @@ -152,7 +152,7 @@ func (a *ApiHandler) getStateRoot(r *http.Request) (*beaconResponse, error) {
withFinalized(canonicalRoot == root && *slot <= a.forkchoiceStore.FinalizedSlot()), nil
}

func (a *ApiHandler) getFullState(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getFullState(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

tx, err := a.indiciesDB.BeginRo(ctx)
Expand Down Expand Up @@ -210,7 +210,7 @@ type finalityCheckpointsResponse struct {
PreviousJustifiedCheckpoint solid.Checkpoint `json:"previous_justified_checkpoint"`
}

func (a *ApiHandler) getFinalityCheckpoints(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getFinalityCheckpoints(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

tx, err := a.indiciesDB.BeginRo(ctx)
Expand Down Expand Up @@ -267,7 +267,7 @@ type syncCommitteesResponse struct {
ValidatorAggregates [][]string `json:"validator_aggregates"`
}

func (a *ApiHandler) getSyncCommittees(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getSyncCommittees(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

tx, err := a.indiciesDB.BeginRo(ctx)
Expand Down
6 changes: 3 additions & 3 deletions cl/beacon/handler/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func checkValidValidatorId(s string) (bool, error) {
return false, nil
}

func (a *ApiHandler) getAllValidators(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getAllValidators(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

tx, err := a.indiciesDB.BeginRo(ctx)
Expand Down Expand Up @@ -308,7 +308,7 @@ func parseQueryValidatorIndicies(tx kv.Tx, ids []string) ([]uint64, error) {
return filterIndicies, nil
}

func (a *ApiHandler) getSingleValidator(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getSingleValidator(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

tx, err := a.indiciesDB.BeginRo(ctx)
Expand Down Expand Up @@ -375,7 +375,7 @@ func (a *ApiHandler) getSingleValidator(r *http.Request) (*beaconResponse, error
return responseValidator(validatorIndex, stateEpoch, state.Balances(), state.Validators(), *slot <= a.forkchoiceStore.FinalizedSlot())
}

func (a *ApiHandler) getAllValidatorsBalances(r *http.Request) (*beaconResponse, error) {
func (a *ApiHandler) getAllValidatorsBalances(w http.ResponseWriter, r *http.Request) (*beaconResponse, error) {
ctx := r.Context()

tx, err := a.indiciesDB.BeginRo(ctx)
Expand Down
Loading

0 comments on commit bab123c

Please sign in to comment.