mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-08 02:31:19 +00:00
d6ae838bbf
* WIP * event stream wip * returning nil * temp removing some tests * wip health checks * fixing conficts * updating fields based on linting * fixing more errors * fixing mocks * fixing more mocks * fixing more linting * removing white space for lint * fixing log format * gaz * reverting changes on grpc * fixing unit tests * adding in tests for health tracker and event stream * adding more tests for streaming slot * gaz * Update api/client/event/event_stream.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * review comments * Update validator/client/runner.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update validator/client/validator.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update validator/client/validator.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update validator/client/validator.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update validator/client/validator.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update validator/client/beacon-api/beacon_api_validator_client.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update validator/client/validator.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update validator/client/validator.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * addressing radek comments * Update validator/client/validator.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * addressing review feedback * moving things to below next slot ticker * fixing tests * update naming * adding TODO comment * Update api/client/beacon/health.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * addressing comments * fixing broken linting * fixing more import issues * fixing more import issues * linting * updating based on radek's comments * addressing more comments * fixing nogo error * fixing duplicate import * gaz * adding radek's review suggestion * Update proto/prysm/v1alpha1/node.proto Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com> * preston review comments * Update api/client/event/event_stream.go Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com> * Update validator/client/validator.go Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com> * addressing some more preston review items * fixing tests for linting * fixing missed linting * updating based on feedback to simplify * adding interface check at the top * reverting some comments * cleaning up intatiations * reworking the health tracker * fixing linting * fixing more linting to adhear to interface * adding interface check at the the top of the file * fixing unit tests * attempting to fix dependency cycle * addressing radek's comment * Update validator/client/beacon-api/beacon_api_validator_client.go Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com> * adding more tests and feedback items * fixing TODO comment --------- Co-authored-by: Radosław Kapka <rkapka@wp.pl> Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
137 lines
3.8 KiB
Go
137 lines
3.8 KiB
Go
package beacon_api
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/prysmaticlabs/prysm/v5/api"
|
|
"github.com/prysmaticlabs/prysm/v5/network/httputil"
|
|
)
|
|
|
|
type JsonRestHandler interface {
|
|
Get(ctx context.Context, endpoint string, resp interface{}) error
|
|
Post(ctx context.Context, endpoint string, headers map[string]string, data *bytes.Buffer, resp interface{}) error
|
|
HttpClient() *http.Client
|
|
Host() string
|
|
}
|
|
|
|
type BeaconApiJsonRestHandler struct {
|
|
client http.Client
|
|
host string
|
|
}
|
|
|
|
// NewBeaconApiJsonRestHandler returns a JsonRestHandler
|
|
func NewBeaconApiJsonRestHandler(client http.Client, host string) JsonRestHandler {
|
|
return &BeaconApiJsonRestHandler{
|
|
client: client,
|
|
host: host,
|
|
}
|
|
}
|
|
|
|
// GetHttpClient returns the underlying HTTP client of the handler
|
|
func (c BeaconApiJsonRestHandler) HttpClient() *http.Client {
|
|
return &c.client
|
|
}
|
|
|
|
// GetHost returns the underlying HTTP host
|
|
func (c BeaconApiJsonRestHandler) Host() string {
|
|
return c.host
|
|
}
|
|
|
|
// Get sends a GET request and decodes the response body as a JSON object into the passed in object.
|
|
// If an HTTP error is returned, the body is decoded as a DefaultJsonError JSON object and returned as the first return value.
|
|
func (c BeaconApiJsonRestHandler) Get(ctx context.Context, endpoint string, resp interface{}) error {
|
|
url := c.host + endpoint
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to create request for endpoint %s", url)
|
|
}
|
|
|
|
httpResp, err := c.client.Do(req)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to perform request for endpoint %s", url)
|
|
}
|
|
defer func() {
|
|
if err := httpResp.Body.Close(); err != nil {
|
|
return
|
|
}
|
|
}()
|
|
|
|
return decodeResp(httpResp, resp)
|
|
}
|
|
|
|
// Post sends a POST request and decodes the response body as a JSON object into the passed in object.
|
|
// If an HTTP error is returned, the body is decoded as a DefaultJsonError JSON object and returned as the first return value.
|
|
func (c BeaconApiJsonRestHandler) Post(
|
|
ctx context.Context,
|
|
apiEndpoint string,
|
|
headers map[string]string,
|
|
data *bytes.Buffer,
|
|
resp interface{},
|
|
) error {
|
|
if data == nil {
|
|
return errors.New("data is nil")
|
|
}
|
|
|
|
url := c.host + apiEndpoint
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, data)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to create request for endpoint %s", url)
|
|
}
|
|
|
|
for headerKey, headerValue := range headers {
|
|
req.Header.Set(headerKey, headerValue)
|
|
}
|
|
req.Header.Set("Content-Type", api.JsonMediaType)
|
|
|
|
httpResp, err := c.client.Do(req)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to perform request for endpoint %s", url)
|
|
}
|
|
defer func() {
|
|
if err = httpResp.Body.Close(); err != nil {
|
|
return
|
|
}
|
|
}()
|
|
|
|
return decodeResp(httpResp, resp)
|
|
}
|
|
|
|
func decodeResp(httpResp *http.Response, resp interface{}) error {
|
|
body, err := io.ReadAll(httpResp.Body)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to read response body for %s", httpResp.Request.URL)
|
|
}
|
|
|
|
if httpResp.Header.Get("Content-Type") != api.JsonMediaType {
|
|
// 2XX codes are a success
|
|
if strings.HasPrefix(httpResp.Status, "2") {
|
|
return nil
|
|
}
|
|
return &httputil.DefaultJsonError{Code: httpResp.StatusCode, Message: string(body)}
|
|
}
|
|
|
|
decoder := json.NewDecoder(bytes.NewBuffer(body))
|
|
// non-2XX codes are a failure
|
|
if !strings.HasPrefix(httpResp.Status, "2") {
|
|
errorJson := &httputil.DefaultJsonError{}
|
|
if err = decoder.Decode(errorJson); err != nil {
|
|
return errors.Wrapf(err, "failed to decode response body into error json for %s", httpResp.Request.URL)
|
|
}
|
|
return errorJson
|
|
}
|
|
// resp is nil for requests that do not return anything.
|
|
if resp != nil {
|
|
if err = decoder.Decode(resp); err != nil {
|
|
return errors.Wrapf(err, "failed to decode response body into json for %s", httpResp.Request.URL)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|