prysm-pulse/endtoend/evaluators/api_gateway_v1.go
Raul Jordan bdb09ca9ea
V1Alpha1 gRPC Gateway End-to-End Test Evaluators (#9375)
* add in initial evaluator for gateway v1alpha1

* add gazelle

* build

* compare

* functional options and tool for local verification

* chain head response compare base64

* compare validators request

* add validators compare

* more compare

* passing validator comparisons

* compare attestations pool

* compare atts

* begin peers test

* e2e verifiers

* correct port

* renaming

* evaluators

* rem api compare tool

* peer compare tests

* deepsource

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-08-16 20:31:21 +00:00

256 lines
7.6 KiB
Go

package evaluators
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/pkg/errors"
e2e "github.com/prysmaticlabs/prysm/endtoend/params"
"github.com/prysmaticlabs/prysm/endtoend/policies"
e2etypes "github.com/prysmaticlabs/prysm/endtoend/types"
"google.golang.org/grpc"
)
type stateValidatorsResponseJson struct {
Data []*validatorContainerJson `json:"data"`
}
type validatorContainerJson struct {
Index string `json:"index"`
Balance string `json:"balance"`
Status string `json:"status"`
Validator *validatorJson `json:"validator"`
}
type validatorJson struct {
PublicKey string `json:"pubkey"`
WithdrawalCredentials string `json:"withdrawal_credentials"`
EffectiveBalance string `json:"effective_balance"`
Slashed bool `json:"slashed"`
ActivationEligibilityEpoch string `json:"activation_eligibility_epoch"`
ActivationEpoch string `json:"activation_epoch"`
ExitEpoch string `json:"exit_epoch"`
WithdrawableEpoch string `json:"withdrawable_epoch"`
}
// APIGatewayV1VerifyIntegrity of our API gateway for the Prysm v1 API.
// This ensures our gRPC HTTP gateway returns good data compared to some fixtures.
var APIGatewayV1VerifyIntegrity = e2etypes.Evaluator{
Name: "api_gateway_v1_verify_integrity_epoch_%d",
Policy: policies.OnEpoch(1),
Evaluation: apiVerifyValidators,
}
func apiVerifyValidators(conns ...*grpc.ClientConn) error {
count := len(conns)
for i := 0; i < count; i++ {
resp, err := http.Get(
fmt.Sprintf("http://localhost:%d/eth/v1/beacon/states/head/validators?status=exited", e2e.TestParams.BeaconNodeRPCPort+i+30),
)
if err != nil {
// Continue if the connection fails, regular flake.
continue
}
if resp.StatusCode != http.StatusOK {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
return fmt.Errorf("expected status code OK for beacon node %d, received %v with body %s", i, resp.StatusCode, body)
}
validators := &stateValidatorsResponseJson{}
if err = json.NewDecoder(resp.Body).Decode(&validators); err != nil {
return err
}
if len(validators.Data) != 0 {
return fmt.Errorf("expected no exited validators to be returned from the API request for beacon node %d", i)
}
resp, err = http.Get(
fmt.Sprintf("http://localhost:%d/eth/v1/beacon/states/head/validators?id=100&id=200", e2e.TestParams.BeaconNodeRPCPort+i+30),
)
if err != nil {
// Continue if the connection fails, regular flake.
continue
}
if resp.StatusCode != http.StatusOK {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
return fmt.Errorf("expected status code OK for beacon node %d, received %v with body %s", i, resp.StatusCode, body)
}
validators = &stateValidatorsResponseJson{}
if err = json.NewDecoder(resp.Body).Decode(&validators); err != nil {
return err
}
if len(validators.Data) != 2 {
return fmt.Errorf("expected 2 validators to be returned from the API request for beacon node %d", i)
}
if err = assertValidator(validators.Data[0]); err != nil {
return errors.Wrapf(err, "incorrect validator data returned from the API request for beacon node %d", i)
}
if err = assertValidator(validators.Data[1]); err != nil {
return errors.Wrapf(err, "incorrect validator data returned from the API request for beacon node %d", i)
}
if err = resp.Body.Close(); err != nil {
return err
}
time.Sleep(connTimeDelay)
}
return nil
}
func assertValidator(v *validatorContainerJson) error {
if v == nil {
return errors.New("validator is nil")
}
if v.Index != "100" && v.Index != "200" {
return fmt.Errorf("unexpected validator index '%s'", v.Index)
}
valid := false
var field, expected, actual string
switch v.Index {
case "100":
if v.Balance != "32000000000" {
field = "Balance"
expected = "32000000000"
actual = v.Balance
break
}
if v.Status != "active_ongoing" {
field = "Status"
expected = "active_ongoing"
actual = v.Status
break
}
if v.Validator == nil {
return errors.New("validator is nil")
}
if v.Validator.PublicKey != "0x8931cd39ec3133b6ec91f26eec4de555cd7966086b1993dfe69c2b16e80adc62ce82d353b3356d8cc249e4e2d4254122" {
field = "PublicKey"
expected = "0x8931cd39ec3133b6ec91f26eec4de555cd7966086b1993dfe69c2b16e80adc62ce82d353b3356d8cc249e4e2d4254122"
actual = v.Validator.PublicKey
break
}
if v.Validator.WithdrawalCredentials != "0x00b5a389a138ec5069e430a91ec2884660fbb77a4bffdefd03f5e5769c2ba1a9" {
field = "WithdrawalCredentials"
expected = "0x00b5a389a138ec5069e430a91ec2884660fbb77a4bffdefd03f5e5769c2ba1a9"
actual = v.Validator.WithdrawalCredentials
break
}
if v.Validator.EffectiveBalance != "32000000000" {
field = "EffectiveBalance"
expected = "32000000000"
actual = v.Validator.EffectiveBalance
break
}
if v.Validator.Slashed {
field = "Slashed"
expected = "32000000000"
actual = "true"
break
}
if v.Validator.ActivationEligibilityEpoch != "0" {
field = "ActivationEligibilityEpoch"
expected = "0"
actual = v.Validator.ActivationEligibilityEpoch
break
}
if v.Validator.ActivationEpoch != "0" {
field = "ActivationEpoch"
expected = "0"
actual = v.Validator.ActivationEpoch
break
}
if v.Validator.ExitEpoch != "18446744073709551615" {
field = "ExitEpoch"
expected = "18446744073709551615"
actual = v.Validator.ExitEpoch
break
}
if v.Validator.WithdrawableEpoch != "18446744073709551615" {
field = "WithdrawableEpoch"
expected = "18446744073709551615"
actual = v.Validator.WithdrawableEpoch
break
}
valid = true
case "200":
if v.Balance != "32000000000" {
field = "Balance"
expected = "32000000000"
actual = v.Balance
break
}
if v.Status != "active_ongoing" {
field = "Status"
expected = "active_ongoing"
actual = v.Status
break
}
if v.Validator == nil {
return errors.New("validator is nil")
}
if v.Validator.PublicKey != "0x8b4ff71ee947785f545c017bbb9ce84c3f6a90097368cf79663b2e11acc53e18e8f7159919784f4d28282cb39a7113f7" {
field = "PublicKey"
expected = "0x8b4ff71ee947785f545c017bbb9ce84c3f6a90097368cf79663b2e11acc53e18e8f7159919784f4d28282cb39a7113f7"
actual = v.Validator.PublicKey
break
}
if v.Validator.WithdrawalCredentials != "0x00b9ea0e53f64def81fe2e783a8bb02e57fb519f56a7224f93f2d37e1572417d" {
field = "WithdrawalCredentials"
expected = "0x00b9ea0e53f64def81fe2e783a8bb02e57fb519f56a7224f93f2d37e1572417d"
actual = v.Validator.WithdrawalCredentials
break
}
if v.Validator.EffectiveBalance != "32000000000" {
field = "EffectiveBalance"
expected = "32000000000"
actual = v.Validator.EffectiveBalance
break
}
if v.Validator.Slashed {
field = "Slashed"
expected = "32000000000"
actual = "true"
break
}
if v.Validator.ActivationEligibilityEpoch != "0" {
field = "ActivationEligibilityEpoch"
expected = "0"
actual = v.Validator.ActivationEligibilityEpoch
break
}
if v.Validator.ActivationEpoch != "0" {
field = "ActivationEpoch"
expected = "0"
actual = v.Validator.ActivationEpoch
break
}
if v.Validator.ExitEpoch != "18446744073709551615" {
field = "ExitEpoch"
expected = "18446744073709551615"
actual = v.Validator.ExitEpoch
break
}
if v.Validator.WithdrawableEpoch != "18446744073709551615" {
field = "WithdrawableEpoch"
expected = "18446744073709551615"
actual = v.Validator.WithdrawableEpoch
break
}
valid = true
}
if !valid {
return fmt.Errorf("value of '%s' was expected to be '%s' but was '%s'", field, expected, actual)
}
return nil
}