prysm-pulse/testing/endtoend/evaluators/api_middleware.go
Radosław Kapka e22258caa9
HTTP validator APIs (#12887)
* GetValidators in progress

* in progress

* completed implementation of GetValidators + some tests

* typo

* completed tests for GetValidators

* GetValidator

* GetValidatorBalances

* register

* more tests and e2e fix

* middleware cleanup

* remove struct

* handle all ignored

* test fixes

* more test fixes

* even more test fixes

* remove unused structs

* docs

* fix validator count test

* build fix

* add length checks

* lint fix

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2023-09-21 18:16:59 +00:00

94 lines
2.8 KiB
Go

package evaluators
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/prysmaticlabs/prysm/v4/proto/eth/service"
ethpbv2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2"
"github.com/prysmaticlabs/prysm/v4/testing/endtoend/helpers"
"github.com/prysmaticlabs/prysm/v4/testing/endtoend/params"
"github.com/prysmaticlabs/prysm/v4/testing/endtoend/policies"
e2etypes "github.com/prysmaticlabs/prysm/v4/testing/endtoend/types"
"google.golang.org/grpc"
)
// APIMiddlewareVerifyIntegrity tests our API Middleware for the official Ethereum API.
// This ensures our API Middleware returns good data compared to gRPC.
var APIMiddlewareVerifyIntegrity = e2etypes.Evaluator{
Name: "api_middleware_verify_integrity_epoch_%d",
Policy: policies.OnEpoch(helpers.AltairE2EForkEpoch),
Evaluation: apiMiddlewareVerify,
}
const (
v1MiddlewarePathTemplate = "http://localhost:%d/eth/v1"
)
func apiMiddlewareVerify(_ *e2etypes.EvaluationContext, conns ...*grpc.ClientConn) error {
for beaconNodeIdx, conn := range conns {
if err := runAPIComparisonFunctions(
beaconNodeIdx,
conn,
withCompareSyncCommittee,
); err != nil {
return err
}
}
return nil
}
func withCompareSyncCommittee(beaconNodeIdx int, conn *grpc.ClientConn) error {
type syncCommitteeValidatorsJson struct {
Validators []string `json:"validators"`
ValidatorAggregates [][]string `json:"validator_aggregates"`
}
type syncCommitteesResponseJson struct {
Data *syncCommitteeValidatorsJson `json:"data"`
}
ctx := context.Background()
beaconClient := service.NewBeaconChainClient(conn)
resp, err := beaconClient.ListSyncCommittees(ctx, &ethpbv2.StateSyncCommitteesRequest{
StateId: []byte("head"),
})
if err != nil {
return err
}
respJSON := &syncCommitteesResponseJson{}
if err := doMiddlewareJSONGetRequestV1(
"/beacon/states/head/sync_committees",
beaconNodeIdx,
respJSON,
); err != nil {
return err
}
if len(respJSON.Data.Validators) != len(resp.Data.Validators) {
return fmt.Errorf(
"API Middleware number of validators %d does not match gRPC %d",
len(respJSON.Data.Validators),
len(resp.Data.Validators),
)
}
if len(respJSON.Data.ValidatorAggregates) != len(resp.Data.ValidatorAggregates) {
return fmt.Errorf(
"API Middleware number of validator aggregates %d does not match gRPC %d",
len(respJSON.Data.ValidatorAggregates),
len(resp.Data.ValidatorAggregates),
)
}
return nil
}
func doMiddlewareJSONGetRequestV1(requestPath string, beaconNodeIdx int, dst interface{}) error {
basePath := fmt.Sprintf(v1MiddlewarePathTemplate, params.TestParams.Ports.PrysmBeaconNodeGatewayPort+beaconNodeIdx)
httpResp, err := http.Get(
basePath + requestPath,
)
if err != nil {
return err
}
return json.NewDecoder(httpResp.Body).Decode(&dst)
}