Skip to content

Commit

Permalink
done
Browse files Browse the repository at this point in the history
  • Loading branch information
domiwei committed Jul 17, 2024
1 parent c6dc7c0 commit 5abe319
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 17 deletions.
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.StatusBadRequest)
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

0 comments on commit 5abe319

Please sign in to comment.