From 2875ce6ee1dfa48ba10fdb1152ec6b2efa58464d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kapka?= Date: Thu, 11 Jan 2024 17:03:35 +0100 Subject: [PATCH] Use a single rest handler (#13446) --- validator/accounts/cli_manager.go | 12 +++++++--- .../beacon_api_beacon_chain_client.go | 9 +------ .../beacon-api/beacon_api_node_client.go | 9 +------ .../beacon-api/beacon_api_validator_client.go | 8 +------ .../client/beacon-api/json_rest_handler.go | 20 ++++++++-------- .../beacon-api/json_rest_handler_test.go | 12 +++++----- .../beacon-api/prysm_beacon_chain_client.go | 9 +------ .../beacon_chain_client_factory.go | 24 +++++-------------- .../node_client_factory.go | 8 +++---- validator/client/service.go | 17 +++++++------ .../validator_client_factory.go | 11 +++++---- validator/rpc/BUILD.bazel | 1 + validator/rpc/beacon.go | 14 ++++++++--- 13 files changed, 66 insertions(+), 88 deletions(-) diff --git a/validator/accounts/cli_manager.go b/validator/accounts/cli_manager.go index de07b4f686e5..c3a6b2e370db 100644 --- a/validator/accounts/cli_manager.go +++ b/validator/accounts/cli_manager.go @@ -3,6 +3,7 @@ package accounts import ( "context" "io" + "net/http" "os" "time" @@ -10,6 +11,7 @@ import ( grpcutil "github.com/prysmaticlabs/prysm/v4/api/grpc" "github.com/prysmaticlabs/prysm/v4/crypto/bls" "github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet" + beaconApi "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api" iface "github.com/prysmaticlabs/prysm/v4/validator/client/iface" nodeClientFactory "github.com/prysmaticlabs/prysm/v4/validator/client/node-client-factory" validatorClientFactory "github.com/prysmaticlabs/prysm/v4/validator/client/validator-client-factory" @@ -80,14 +82,18 @@ func (acm *CLIManager) prepareBeaconClients(ctx context.Context) (*iface.Validat if err != nil { return nil, nil, errors.Wrapf(err, "could not dial endpoint %s", acm.beaconRPCProvider) } - conn := validatorHelpers.NewNodeConnection( grpcConn, acm.beaconApiEndpoint, acm.beaconApiTimeout, ) - validatorClient := validatorClientFactory.NewValidatorClient(conn) - nodeClient := nodeClientFactory.NewNodeClient(conn) + restHandler := &beaconApi.BeaconApiJsonRestHandler{ + HttpClient: http.Client{Timeout: acm.beaconApiTimeout}, + Host: acm.beaconApiEndpoint, + } + validatorClient := validatorClientFactory.NewValidatorClient(conn, restHandler) + nodeClient := nodeClientFactory.NewNodeClient(conn, restHandler) + return &validatorClient, &nodeClient, nil } diff --git a/validator/client/beacon-api/beacon_api_beacon_chain_client.go b/validator/client/beacon-api/beacon_api_beacon_chain_client.go index 08805224deba..1ae598785793 100644 --- a/validator/client/beacon-api/beacon_api_beacon_chain_client.go +++ b/validator/client/beacon-api/beacon_api_beacon_chain_client.go @@ -4,10 +4,8 @@ import ( "bytes" "context" "encoding/json" - "net/http" "reflect" "strconv" - "time" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/golang/protobuf/ptypes/empty" @@ -357,12 +355,7 @@ func (c beaconApiBeaconChainClient) GetValidatorParticipation(ctx context.Contex panic("beaconApiBeaconChainClient.GetValidatorParticipation is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiBeaconChainClientWithFallback.") } -func NewBeaconApiBeaconChainClientWithFallback(host string, timeout time.Duration, fallbackClient iface.BeaconChainClient) iface.BeaconChainClient { - jsonRestHandler := beaconApiJsonRestHandler{ - httpClient: http.Client{Timeout: timeout}, - host: host, - } - +func NewBeaconApiBeaconChainClientWithFallback(jsonRestHandler JsonRestHandler, fallbackClient iface.BeaconChainClient) iface.BeaconChainClient { return &beaconApiBeaconChainClient{ jsonRestHandler: jsonRestHandler, fallbackClient: fallbackClient, diff --git a/validator/client/beacon-api/beacon_api_node_client.go b/validator/client/beacon-api/beacon_api_node_client.go index adc3ff6bf766..d66f26ca19db 100644 --- a/validator/client/beacon-api/beacon_api_node_client.go +++ b/validator/client/beacon-api/beacon_api_node_client.go @@ -2,9 +2,7 @@ package beacon_api import ( "context" - "net/http" "strconv" - "time" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/golang/protobuf/ptypes/empty" @@ -100,12 +98,7 @@ func (c *beaconApiNodeClient) ListPeers(ctx context.Context, in *empty.Empty) (* panic("beaconApiNodeClient.ListPeers is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiNodeClientWithFallback.") } -func NewNodeClientWithFallback(host string, timeout time.Duration, fallbackClient iface.NodeClient) iface.NodeClient { - jsonRestHandler := beaconApiJsonRestHandler{ - httpClient: http.Client{Timeout: timeout}, - host: host, - } - +func NewNodeClientWithFallback(jsonRestHandler JsonRestHandler, fallbackClient iface.NodeClient) iface.NodeClient { return &beaconApiNodeClient{ jsonRestHandler: jsonRestHandler, fallbackClient: fallbackClient, diff --git a/validator/client/beacon-api/beacon_api_validator_client.go b/validator/client/beacon-api/beacon_api_validator_client.go index 67da2d6ebefe..fd9aaa13bd6f 100644 --- a/validator/client/beacon-api/beacon_api_validator_client.go +++ b/validator/client/beacon-api/beacon_api_validator_client.go @@ -2,7 +2,6 @@ package beacon_api import ( "context" - "net/http" "time" "github.com/ethereum/go-ethereum/common/hexutil" @@ -23,12 +22,7 @@ type beaconApiValidatorClient struct { prysmBeaconChainCLient iface.PrysmBeaconChainClient } -func NewBeaconApiValidatorClient(host string, timeout time.Duration) iface.ValidatorClient { - jsonRestHandler := beaconApiJsonRestHandler{ - httpClient: http.Client{Timeout: timeout}, - host: host, - } - +func NewBeaconApiValidatorClient(jsonRestHandler JsonRestHandler) iface.ValidatorClient { return &beaconApiValidatorClient{ genesisProvider: beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}, dutiesProvider: beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}, diff --git a/validator/client/beacon-api/json_rest_handler.go b/validator/client/beacon-api/json_rest_handler.go index 9a7c30e3e312..9271a84826df 100644 --- a/validator/client/beacon-api/json_rest_handler.go +++ b/validator/client/beacon-api/json_rest_handler.go @@ -13,29 +13,29 @@ import ( ) type JsonRestHandler interface { - Get(ctx context.Context, query string, resp interface{}) error + 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 } -type beaconApiJsonRestHandler struct { - httpClient http.Client - host string +type BeaconApiJsonRestHandler struct { + HttpClient http.Client + Host string } // 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 { +func (c BeaconApiJsonRestHandler) Get(ctx context.Context, endpoint string, resp interface{}) error { if resp == nil { return errors.New("resp is nil") } - url := c.host + endpoint + 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.httpClient.Do(req) + httpResp, err := c.HttpClient.Do(req) if err != nil { return errors.Wrapf(err, "failed to perform request for endpoint %s", url) } @@ -50,7 +50,7 @@ func (c beaconApiJsonRestHandler) Get(ctx context.Context, endpoint string, 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( +func (c BeaconApiJsonRestHandler) Post( ctx context.Context, apiEndpoint string, headers map[string]string, @@ -61,7 +61,7 @@ func (c beaconApiJsonRestHandler) Post( return errors.New("data is nil") } - url := c.host + apiEndpoint + 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) @@ -72,7 +72,7 @@ func (c beaconApiJsonRestHandler) Post( } req.Header.Set("Content-Type", api.JsonMediaType) - httpResp, err := c.httpClient.Do(req) + httpResp, err := c.HttpClient.Do(req) if err != nil { return errors.Wrapf(err, "failed to perform request for endpoint %s", url) } diff --git a/validator/client/beacon-api/json_rest_handler_test.go b/validator/client/beacon-api/json_rest_handler_test.go index b9652a6d6f90..03ba8d9e3088 100644 --- a/validator/client/beacon-api/json_rest_handler_test.go +++ b/validator/client/beacon-api/json_rest_handler_test.go @@ -40,9 +40,9 @@ func TestGet(t *testing.T) { server := httptest.NewServer(mux) defer server.Close() - jsonRestHandler := beaconApiJsonRestHandler{ - httpClient: http.Client{Timeout: time.Second * 5}, - host: server.URL, + jsonRestHandler := BeaconApiJsonRestHandler{ + HttpClient: http.Client{Timeout: time.Second * 5}, + Host: server.URL, } resp := &beacon.GetGenesisResponse{} require.NoError(t, jsonRestHandler.Get(ctx, endpoint+"?arg1=abc&arg2=def", resp)) @@ -86,9 +86,9 @@ func TestPost(t *testing.T) { server := httptest.NewServer(mux) defer server.Close() - jsonRestHandler := beaconApiJsonRestHandler{ - httpClient: http.Client{Timeout: time.Second * 5}, - host: server.URL, + jsonRestHandler := BeaconApiJsonRestHandler{ + HttpClient: http.Client{Timeout: time.Second * 5}, + Host: server.URL, } resp := &beacon.GetGenesisResponse{} require.NoError(t, jsonRestHandler.Post(ctx, endpoint, headers, bytes.NewBuffer(dataBytes), resp)) diff --git a/validator/client/beacon-api/prysm_beacon_chain_client.go b/validator/client/beacon-api/prysm_beacon_chain_client.go index 6a9876ac7042..c8227674677b 100644 --- a/validator/client/beacon-api/prysm_beacon_chain_client.go +++ b/validator/client/beacon-api/prysm_beacon_chain_client.go @@ -3,11 +3,9 @@ package beacon_api import ( "context" "fmt" - "net/http" neturl "net/url" "strconv" "strings" - "time" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/validator" @@ -16,12 +14,7 @@ import ( ) // NewPrysmBeaconChainClient returns implementation of iface.PrysmBeaconChainClient. -func NewPrysmBeaconChainClient(host string, timeout time.Duration, nodeClient iface.NodeClient) iface.PrysmBeaconChainClient { - jsonRestHandler := beaconApiJsonRestHandler{ - httpClient: http.Client{Timeout: timeout}, - host: host, - } - +func NewPrysmBeaconChainClient(jsonRestHandler JsonRestHandler, nodeClient iface.NodeClient) iface.PrysmBeaconChainClient { return prysmBeaconChainClient{ jsonRestHandler: jsonRestHandler, nodeClient: nodeClient, diff --git a/validator/client/beacon-chain-client-factory/beacon_chain_client_factory.go b/validator/client/beacon-chain-client-factory/beacon_chain_client_factory.go index 0cc5d888584e..3b15003085e2 100644 --- a/validator/client/beacon-chain-client-factory/beacon_chain_client_factory.go +++ b/validator/client/beacon-chain-client-factory/beacon_chain_client_factory.go @@ -9,30 +9,18 @@ import ( validatorHelpers "github.com/prysmaticlabs/prysm/v4/validator/helpers" ) -func NewBeaconChainClient(validatorConn validatorHelpers.NodeConnection) iface.BeaconChainClient { +func NewBeaconChainClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler beaconApi.JsonRestHandler) iface.BeaconChainClient { grpcClient := grpcApi.NewGrpcBeaconChainClient(validatorConn.GetGrpcClientConn()) - featureFlags := features.Get() - - if featureFlags.EnableBeaconRESTApi { - return beaconApi.NewBeaconApiBeaconChainClientWithFallback( - validatorConn.GetBeaconApiUrl(), - validatorConn.GetBeaconApiTimeout(), - grpcClient, - ) + if features.Get().EnableBeaconRESTApi { + return beaconApi.NewBeaconApiBeaconChainClientWithFallback(jsonRestHandler, grpcClient) } else { return grpcClient } } -func NewPrysmBeaconClient(validatorConn validatorHelpers.NodeConnection) iface.PrysmBeaconChainClient { - featureFlags := features.Get() - - if featureFlags.EnableBeaconRESTApi { - return beaconApi.NewPrysmBeaconChainClient( - validatorConn.GetBeaconApiUrl(), - validatorConn.GetBeaconApiTimeout(), - nodeClientFactory.NewNodeClient(validatorConn), - ) +func NewPrysmBeaconClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler beaconApi.JsonRestHandler) iface.PrysmBeaconChainClient { + if features.Get().EnableBeaconRESTApi { + return beaconApi.NewPrysmBeaconChainClient(jsonRestHandler, nodeClientFactory.NewNodeClient(validatorConn, jsonRestHandler)) } else { return grpcApi.NewGrpcPrysmBeaconChainClient(validatorConn.GetGrpcClientConn()) } diff --git a/validator/client/node-client-factory/node_client_factory.go b/validator/client/node-client-factory/node_client_factory.go index 90f60c8c9528..65a6158bbe5b 100644 --- a/validator/client/node-client-factory/node_client_factory.go +++ b/validator/client/node-client-factory/node_client_factory.go @@ -8,12 +8,10 @@ import ( validatorHelpers "github.com/prysmaticlabs/prysm/v4/validator/helpers" ) -func NewNodeClient(validatorConn validatorHelpers.NodeConnection) iface.NodeClient { +func NewNodeClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler beaconApi.JsonRestHandler) iface.NodeClient { grpcClient := grpcApi.NewNodeClient(validatorConn.GetGrpcClientConn()) - featureFlags := features.Get() - - if featureFlags.EnableBeaconRESTApi { - return beaconApi.NewNodeClientWithFallback(validatorConn.GetBeaconApiUrl(), validatorConn.GetBeaconApiTimeout(), grpcClient) + if features.Get().EnableBeaconRESTApi { + return beaconApi.NewNodeClientWithFallback(jsonRestHandler, grpcClient) } else { return grpcClient } diff --git a/validator/client/service.go b/validator/client/service.go index 566ed0515319..a499dfca0f2e 100644 --- a/validator/client/service.go +++ b/validator/client/service.go @@ -2,6 +2,7 @@ package client import ( "context" + "net/http" "strings" "time" @@ -20,6 +21,7 @@ import ( "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet" + beaconApi "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api" beaconChainClientFactory "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-chain-client-factory" "github.com/prysmaticlabs/prysm/v4/validator/client/iface" nodeClientFactory "github.com/prysmaticlabs/prysm/v4/validator/client/node-client-factory" @@ -189,15 +191,16 @@ func (v *ValidatorService) Start() { return } - validatorClient := validatorClientFactory.NewValidatorClient(v.conn) - beaconClient := beaconChainClientFactory.NewBeaconChainClient(v.conn) - prysmBeaconClient := beaconChainClientFactory.NewPrysmBeaconClient(v.conn) + restHandler := &beaconApi.BeaconApiJsonRestHandler{ + HttpClient: http.Client{Timeout: v.conn.GetBeaconApiTimeout()}, + Host: v.conn.GetBeaconApiUrl(), + } valStruct := &validator{ db: v.db, - validatorClient: validatorClient, - beaconClient: beaconClient, - node: nodeClientFactory.NewNodeClient(v.conn), + validatorClient: validatorClientFactory.NewValidatorClient(v.conn, restHandler), + beaconClient: beaconChainClientFactory.NewBeaconChainClient(v.conn, restHandler), + node: nodeClientFactory.NewNodeClient(v.conn, restHandler), graffiti: v.graffiti, logValidatorBalances: v.logValidatorBalances, emitAccountMetrics: v.emitAccountMetrics, @@ -221,7 +224,7 @@ func (v *ValidatorService) Start() { Web3SignerConfig: v.Web3SignerConfig, proposerSettings: v.proposerSettings, walletInitializedChannel: make(chan *wallet.Wallet, 1), - prysmBeaconClient: prysmBeaconClient, + prysmBeaconClient: beaconChainClientFactory.NewPrysmBeaconClient(v.conn, restHandler), validatorsRegBatchSize: v.validatorsRegBatchSize, } diff --git a/validator/client/validator-client-factory/validator_client_factory.go b/validator/client/validator-client-factory/validator_client_factory.go index cb0a9f72b9a0..a3e71b74d222 100644 --- a/validator/client/validator-client-factory/validator_client_factory.go +++ b/validator/client/validator-client-factory/validator_client_factory.go @@ -8,11 +8,12 @@ import ( validatorHelpers "github.com/prysmaticlabs/prysm/v4/validator/helpers" ) -func NewValidatorClient(validatorConn validatorHelpers.NodeConnection) iface.ValidatorClient { - featureFlags := features.Get() - - if featureFlags.EnableBeaconRESTApi { - return beaconApi.NewBeaconApiValidatorClient(validatorConn.GetBeaconApiUrl(), validatorConn.GetBeaconApiTimeout()) +func NewValidatorClient( + validatorConn validatorHelpers.NodeConnection, + jsonRestHandler beaconApi.JsonRestHandler, +) iface.ValidatorClient { + if features.Get().EnableBeaconRESTApi { + return beaconApi.NewBeaconApiValidatorClient(jsonRestHandler) } else { return grpcApi.NewGrpcValidatorClient(validatorConn.GetGrpcClientConn()) } diff --git a/validator/rpc/BUILD.bazel b/validator/rpc/BUILD.bazel index adaa8eff80e1..45b2f120c766 100644 --- a/validator/rpc/BUILD.bazel +++ b/validator/rpc/BUILD.bazel @@ -49,6 +49,7 @@ go_library( "//validator/accounts/petnames:go_default_library", "//validator/accounts/wallet:go_default_library", "//validator/client:go_default_library", + "//validator/client/beacon-api:go_default_library", "//validator/client/beacon-chain-client-factory:go_default_library", "//validator/client/iface:go_default_library", "//validator/client/node-client-factory:go_default_library", diff --git a/validator/rpc/beacon.go b/validator/rpc/beacon.go index d79bb44e0e55..dd177d00fc7e 100644 --- a/validator/rpc/beacon.go +++ b/validator/rpc/beacon.go @@ -1,6 +1,8 @@ package rpc import ( + "net/http" + middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpcretry "github.com/grpc-ecosystem/go-grpc-middleware/retry" grpcopentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing" @@ -9,6 +11,7 @@ import ( grpcutil "github.com/prysmaticlabs/prysm/v4/api/grpc" ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/validator/client" + beaconApi "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api" beaconChainClientFactory "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-chain-client-factory" nodeClientFactory "github.com/prysmaticlabs/prysm/v4/validator/client/node-client-factory" validatorClientFactory "github.com/prysmaticlabs/prysm/v4/validator/client/validator-client-factory" @@ -51,8 +54,13 @@ func (s *Server) registerBeaconClient() error { s.beaconApiTimeout, ) - s.beaconChainClient = beaconChainClientFactory.NewBeaconChainClient(conn) - s.beaconNodeClient = nodeClientFactory.NewNodeClient(conn) - s.beaconNodeValidatorClient = validatorClientFactory.NewValidatorClient(conn) + restHandler := &beaconApi.BeaconApiJsonRestHandler{ + HttpClient: http.Client{Timeout: s.beaconApiTimeout}, + Host: s.beaconApiEndpoint, + } + s.beaconChainClient = beaconChainClientFactory.NewBeaconChainClient(conn, restHandler) + s.beaconNodeClient = nodeClientFactory.NewNodeClient(conn, restHandler) + s.beaconNodeValidatorClient = validatorClientFactory.NewValidatorClient(conn, restHandler) + return nil }