Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cl/beacon/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ func (a *ApiHandler) init() {
r.Get("/validators", a.GetEthV1BeaconStatesValidators)
r.Post("/validators", a.PostEthV1BeaconStatesValidators)
r.Get("/validator_balances", a.GetEthV1BeaconValidatorsBalances)
r.Post("/validator_balances", a.PostEthV1BeaconValidatorsBalances)
r.Get("/validators/{validator_id}", beaconhttp.HandleEndpointFunc(a.GetEthV1BeaconStatesValidator))
})
})
Expand Down
61 changes: 44 additions & 17 deletions cl/beacon/handler/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package handler

import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -502,29 +503,36 @@ func (a *ApiHandler) GetEthV1BeaconStatesValidator(w http.ResponseWriter, r *htt
return responseValidator(validatorIndex, stateEpoch, balances, validators, *slot <= a.forkchoiceStore.FinalizedSlot(), isOptimistic)
}

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

tx, err := a.indiciesDB.BeginRo(ctx)
// https://ethereum.github.io/beacon-APIs/#/Beacon/postStateValidatorBalances
func (a *ApiHandler) PostEthV1BeaconValidatorsBalances(w http.ResponseWriter, r *http.Request) {
blockId, err := beaconhttp.StateIdFromRequest(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer tx.Rollback()

blockId, err := beaconhttp.StateIdFromRequest(r)
if err != nil {
validatorIds := []string{}
// read from request body
if err := json.NewDecoder(r.Body).Decode(&validatorIds); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

blockRoot, httpStatus, err := a.blockRootFromStateId(ctx, tx, blockId)
if err != nil {
http.Error(w, err.Error(), httpStatus)
if len(validatorIds) > maxValidatorsLookupFilter {
http.Error(w, fmt.Errorf("too many validators requested").Error(), http.StatusBadRequest)
return
}

isOptimistic := a.forkchoiceStore.IsRootOptimistic(blockRoot)
a.getValidatorBalances(r.Context(), w, blockId, validatorIds)
}

// https://ethereum.github.io/beacon-APIs/#/Beacon/getStateValidatorBalances
func (a *ApiHandler) GetEthV1BeaconValidatorsBalances(w http.ResponseWriter, r *http.Request) {
blockId, err := beaconhttp.StateIdFromRequest(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

validatorIds, err := beaconhttp.StringListFromQueryParams(r, "id")
if err != nil {
Expand All @@ -536,19 +544,38 @@ func (a *ApiHandler) GetEthV1BeaconValidatorsBalances(w http.ResponseWriter, r *
http.Error(w, fmt.Errorf("too many validators requested").Error(), http.StatusBadRequest)
return
}
a.getValidatorBalances(r.Context(), w, blockId, validatorIds)
}

func (a *ApiHandler) getValidatorBalances(ctx context.Context, w http.ResponseWriter, blockId *beaconhttp.SegmentID, validatorIds []string) {
tx, err := a.indiciesDB.BeginRo(ctx)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer tx.Rollback()

blockRoot, httpStatus, err := a.blockRootFromStateId(ctx, tx, blockId)
if err != nil {
http.Error(w, err.Error(), httpStatus)
return
}

filterIndicies, err := parseQueryValidatorIndicies(tx, validatorIds)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

isOptimistic := a.forkchoiceStore.IsRootOptimistic(blockRoot)

if blockId.Head() { // Lets see if we point to head, if yes then we need to look at the head state we always keep.
s := a.syncedData.HeadState()
if s == nil {
http.Error(w, fmt.Errorf("node is not synced").Error(), http.StatusServiceUnavailable)
return
}
responseValidatorsBalances(w, filterIndicies, state.Epoch(s), s.Balances(), false, isOptimistic)
responseValidatorsBalances(w, filterIndicies, s.Balances(), false, isOptimistic)
return
}
slot, err := beacon_indicies.ReadBlockSlotByBlockRoot(tx, blockRoot)
Expand All @@ -561,7 +588,6 @@ func (a *ApiHandler) GetEthV1BeaconValidatorsBalances(w http.ResponseWriter, r *
http.Error(w, fmt.Errorf("state not found").Error(), http.StatusNotFound)
return
}
stateEpoch := *slot / a.beaconChainCfg.SlotsPerEpoch

if *slot < a.forkchoiceStore.LowestAvaiableSlot() {
balances, err := a.stateReader.ReadValidatorsBalances(tx, *slot)
Expand All @@ -573,7 +599,7 @@ func (a *ApiHandler) GetEthV1BeaconValidatorsBalances(w http.ResponseWriter, r *

http.Error(w, fmt.Errorf("validators not found, node may node be running in archivial node").Error(), http.StatusNotFound)
}
responseValidatorsBalances(w, filterIndicies, stateEpoch, balances, true, isOptimistic)
responseValidatorsBalances(w, filterIndicies, balances, true, isOptimistic)
return
}
balances, err := a.forkchoiceStore.GetBalances(blockRoot)
Expand All @@ -585,7 +611,7 @@ func (a *ApiHandler) GetEthV1BeaconValidatorsBalances(w http.ResponseWriter, r *
http.Error(w, fmt.Errorf("balances not found").Error(), http.StatusNotFound)
return
}
responseValidatorsBalances(w, filterIndicies, stateEpoch, balances, *slot <= a.forkchoiceStore.FinalizedSlot(), isOptimistic)
responseValidatorsBalances(w, filterIndicies, balances, *slot <= a.forkchoiceStore.FinalizedSlot(), isOptimistic)
}

type directString string
Expand Down Expand Up @@ -679,7 +705,8 @@ func responseValidator(idx uint64, stateEpoch uint64, balances solid.Uint64ListS
return newBeaconResponse(directString(b.String())).WithFinalized(finalized).WithOptimistic(optimistic), err
}

func responseValidatorsBalances(w http.ResponseWriter, filterIndicies []uint64, stateEpoch uint64, balances solid.Uint64ListSSZ, finalized bool, optimistic bool) {
func responseValidatorsBalances(w http.ResponseWriter, filterIndicies []uint64, balances solid.Uint64ListSSZ, finalized bool, optimistic bool) {
// todo: refactor this
b := stringsBuilderPool.Get().(*strings.Builder)
defer stringsBuilderPool.Put(b)
b.Reset()
Expand Down
31 changes: 0 additions & 31 deletions experiment/main.go

This file was deleted.