From a31e8d52c156aad749ea5901c8bdb8ab2f8054ae Mon Sep 17 00:00:00 2001 From: Eddy Zagabe Date: Sat, 17 Aug 2024 16:39:27 +0200 Subject: [PATCH 01/55] feat(relayminer): add `proxy.Ping(...)` capability to test connectivity between relay servers and backend URLs (#1) * relayer: add RelayServers() method to RelayProxy interface; Add Ping(), ServiceIDs(), Forward() method to RelayServer interface; add RelayServers slice with helper method byServiceID * relayer: add forward config entry * relayer: implement ServiceIDs, Forward, and Ping method for synchrounous RPC server * relayer: add RelayServers implementation for RelayProxy * relayer: add Ping and Forward options * relayer: integrate ping option * relayer: add ServePing and ServeForward method to RelayMiner * test proxy.Ping() in test + remove forward feature * add serve ping test * add doc --- .../docs/operate/configs/relayminer_config.md | 16 +++++ .../poktrolld/config/relayminer_config.yaml | 3 + .../relayminer_config_full_example.yaml | 6 ++ .../relayminer_config_localnet_vscode.yaml | 3 + pkg/relayer/cmd/cmd.go | 12 ++++ .../config/relayminer_configs_reader.go | 5 ++ pkg/relayer/config/types.go | 12 ++++ pkg/relayer/interface.go | 9 +++ pkg/relayer/proxy/proxy.go | 28 +++++++- pkg/relayer/proxy/proxy_test.go | 5 ++ pkg/relayer/proxy/synchronous.go | 21 ++++++ pkg/relayer/relayminer.go | 19 +++++ pkg/relayer/relayminer_test.go | 69 +++++++++++++++++++ testutil/testrelayer/proxy.go | 31 +++++++++ 14 files changed, 238 insertions(+), 1 deletion(-) diff --git a/docusaurus/docs/operate/configs/relayminer_config.md b/docusaurus/docs/operate/configs/relayminer_config.md index 3b1272b98..0f5733afe 100644 --- a/docusaurus/docs/operate/configs/relayminer_config.md +++ b/docusaurus/docs/operate/configs/relayminer_config.md @@ -23,6 +23,7 @@ You can find a fully featured example configuration at [relayminer_config_full_e - [`smt_store_path`](#smt_store_path) - [`metrics`](#metrics) - [`pprof`](#pprof) + - [`ping`](#ping) - [Pocket node connectivity](#pocket-node-connectivity) - [`query_node_rpc_url`](#query_node_rpc_url) - [`query_node_grpc_url`](#query_node_grpc_url) @@ -173,6 +174,21 @@ pprof: You can learn how to use that endpoint on the [Performance Troubleshooting](../../develop/developer_guide/performance_troubleshooting.md) page. +### `ping` + +Configures a `ping` server to test the connectivity of every backend URLs. If +all the backend URLs are reachable, the endpoint returns a 200 HTTP +Code. Otherwise, if one or more backend URLs aren't reachable, the service +returns an 500 HTTP Internal server error. + +Example configuration: + +```yaml +ping: + enabled: true + addr: localhost:8081 +``` + ## Pocket node connectivity ```yaml diff --git a/localnet/poktrolld/config/relayminer_config.yaml b/localnet/poktrolld/config/relayminer_config.yaml index 1b9895122..71d71cf94 100644 --- a/localnet/poktrolld/config/relayminer_config.yaml +++ b/localnet/poktrolld/config/relayminer_config.yaml @@ -17,3 +17,6 @@ suppliers: pprof: enabled: false addr: localhost:6060 +ping: + enabled: false + addr: localhost:8082 diff --git a/localnet/poktrolld/config/relayminer_config_full_example.yaml b/localnet/poktrolld/config/relayminer_config_full_example.yaml index 7196024fd..5cf0c4f10 100644 --- a/localnet/poktrolld/config/relayminer_config_full_example.yaml +++ b/localnet/poktrolld/config/relayminer_config_full_example.yaml @@ -18,6 +18,12 @@ pprof: enabled: false addr: localhost:6060 +# Ping server configuration to test the connectivity of every +# suppliers.[].service_config.backend_url +ping: + enabled: false + addr: localhost:8081 + pocket_node: # Pocket node URL exposing the CometBFT JSON-RPC API. # Used by the Cosmos client SDK, event subscriptions, etc. diff --git a/localnet/poktrolld/config/relayminer_config_localnet_vscode.yaml b/localnet/poktrolld/config/relayminer_config_localnet_vscode.yaml index de20c4d13..ee56b0c1c 100644 --- a/localnet/poktrolld/config/relayminer_config_localnet_vscode.yaml +++ b/localnet/poktrolld/config/relayminer_config_localnet_vscode.yaml @@ -47,3 +47,6 @@ suppliers: pprof: enabled: false addr: localhost:6070 +ping: + enabled: false + addr: localhost:8081 diff --git a/pkg/relayer/cmd/cmd.go b/pkg/relayer/cmd/cmd.go index 574f405b4..5278a5e69 100644 --- a/pkg/relayer/cmd/cmd.go +++ b/pkg/relayer/cmd/cmd.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "net" "net/http" "net/url" "os" @@ -139,6 +140,17 @@ func runRelayer(cmd *cobra.Command, _ []string) error { } } + if relayMinerConfig.Ping.Enabled { + ln, err := net.Listen("tcp", relayMinerConfig.Ping.Addr) + if err != nil { + return fmt.Errorf("failed to listen ping server: %w", err) + } + + if err := relayMiner.ServePing(ctx, ln); err != nil { + return fmt.Errorf("failed to start ping server: %w", err) + } + } + // Start the relay miner logger.Info().Msg("Starting relay miner...") if err := relayMiner.Start(ctx); err != nil && !errors.Is(err, http.ErrServerClosed) { diff --git a/pkg/relayer/config/relayminer_configs_reader.go b/pkg/relayer/config/relayminer_configs_reader.go index 1cc708908..319303fe1 100644 --- a/pkg/relayer/config/relayminer_configs_reader.go +++ b/pkg/relayer/config/relayminer_configs_reader.go @@ -42,6 +42,11 @@ func ParseRelayMinerConfigs(configContent []byte) (*RelayMinerConfig, error) { Addr: yamlRelayMinerConfig.Pprof.Addr, } + relayMinerConfig.Ping = &RelayMinerPingConfig{ + Enabled: yamlRelayMinerConfig.Ping.Enabled, + Addr: yamlRelayMinerConfig.Ping.Addr, + } + // Hydrate the pocket node urls if err := relayMinerConfig.HydratePocketNodeUrls(&yamlRelayMinerConfig.PocketNode); err != nil { return nil, err diff --git a/pkg/relayer/config/types.go b/pkg/relayer/config/types.go index 8c6ece4ab..fa47517b1 100644 --- a/pkg/relayer/config/types.go +++ b/pkg/relayer/config/types.go @@ -24,6 +24,12 @@ type YAMLRelayMinerConfig struct { Pprof YAMLRelayMinerPprofConfig `yaml:"pprof"` SmtStorePath string `yaml:"smt_store_path"` Suppliers []YAMLRelayMinerSupplierConfig `yaml:"suppliers"` + Ping YAMLRelayMinerPingConfig `yaml:"ping"` +} + +type YAMLRelayMinerPingConfig struct { + Enabled bool `yaml:"enabled"` + Addr string `yaml:"addr"` } // YAMLRelayMinerPocketNodeConfig is the structure used to unmarshal the pocket @@ -83,6 +89,12 @@ type RelayMinerConfig struct { Pprof *RelayMinerPprofConfig Servers map[string]*RelayMinerServerConfig SmtStorePath string + Ping *RelayMinerPingConfig +} + +type RelayMinerPingConfig struct { + Enabled bool + Addr string } // RelayMinerPocketNodeConfig is the structure resulting from parsing the pocket diff --git a/pkg/relayer/interface.go b/pkg/relayer/interface.go index ee9c8e484..586357c82 100644 --- a/pkg/relayer/interface.go +++ b/pkg/relayer/interface.go @@ -73,6 +73,9 @@ type RelayerProxy interface { // TODO_TECHDEBT(@red-0ne): This method should be moved out of the RelayerProxy interface // that should not be responsible for signing relay responses. SignRelayResponse(relayResponse *servicetypes.RelayResponse, supplierOperatorAddr string) error + + // Ping tests the connectivity between all the managed relay servers and their respective backend URLs. + Ping(ctx context.Context) []error } type RelayerProxyOption func(RelayerProxy) @@ -84,8 +87,14 @@ type RelayServer interface { // Stop terminates the service server and returns an error if it fails. Stop(ctx context.Context) error + + // Ping tests the connection between the relay server and its backend URL. + Ping(ctx context.Context) error } +// RelayServers aggregates a slice of RelayServer interface. +type RelayServers []RelayServer + // RelayerSessionsManager is responsible for managing the relayer's session lifecycles. // It handles the creation and retrieval of SMSTs (trees) for a given session, as // well as the respective and subsequent claim creation and proof submission. diff --git a/pkg/relayer/proxy/proxy.go b/pkg/relayer/proxy/proxy.go index 9a76eb953..7bcd7cff2 100644 --- a/pkg/relayer/proxy/proxy.go +++ b/pkg/relayer/proxy/proxy.go @@ -151,7 +151,6 @@ func (rp *relayerProxy) Start(ctx context.Context) error { if err := rp.BuildProvidedServices(ctx); err != nil { return err } - // Start the ring cache. rp.ringCache.Start(ctx) @@ -166,6 +165,11 @@ func (rp *relayerProxy) Start(ctx context.Context) error { for _, relayServer := range rp.servers { server := relayServer // create a new variable scoped to the anonymous function + + if err := server.Ping(ctx); err != nil { + return err + } + startGroup.Go(func() error { return server.Start(ctx) }) } @@ -206,3 +210,25 @@ func (rp *relayerProxy) validateConfig() error { return nil } + +// Ping tests the connectivity between all the managed relay servers and their respective backend URLs. +func (rp *relayerProxy) Ping(ctx context.Context) []error { + errs := make([]error, len(rp.servers)) + + var i int + for _, srv := range rp.servers { + if err := srv.Ping(ctx); err != nil { + rp.logger.Error().Err(err). + Msg("an unexpected error occured while pinging backend URL") + errs[i] = err + } + + i++ + } + + if len(errs) > 0 { + return errs + } + + return nil +} diff --git a/pkg/relayer/proxy/proxy_test.go b/pkg/relayer/proxy/proxy_test.go index b9cb0b642..774757592 100644 --- a/pkg/relayer/proxy/proxy_test.go +++ b/pkg/relayer/proxy/proxy_test.go @@ -151,6 +151,11 @@ func TestRelayerProxy_StartAndStop(t *testing.T) { // Block so relayerProxy has sufficient time to start time.Sleep(100 * time.Millisecond) + errs := rp.Ping(ctx) + for _, err := range errs { + require.NoError(t, err) + } + // Test that RelayerProxy is handling requests (ignoring the actual response content) res, err := http.DefaultClient.Get(fmt.Sprintf("http://%s/", servicesConfigMap[defaultRelayMinerServer].ListenAddress)) require.NoError(t, err) diff --git a/pkg/relayer/proxy/synchronous.go b/pkg/relayer/proxy/synchronous.go index a94af25dc..77761641d 100644 --- a/pkg/relayer/proxy/synchronous.go +++ b/pkg/relayer/proxy/synchronous.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "crypto/tls" + "errors" "fmt" "io" "net/http" @@ -97,6 +98,26 @@ func (sync *synchronousRPCServer) Stop(ctx context.Context) error { return sync.server.Shutdown(ctx) } +// Ping tries to dial the suppliers backend URLs to test the connection. +func (sync *synchronousRPCServer) Ping(ctx context.Context) error { + for _, supplierCfg := range sync.serverConfig.SupplierConfigsMap { + c := &http.Client{Timeout: 2 * time.Second} + + resp, err := c.Head(supplierCfg.ServiceConfig.BackendUrl.String()) + if err != nil { + return err + } + _ = resp.Body.Close() + + if resp.StatusCode >= http.StatusInternalServerError { + return errors.New("ping failed") + } + + } + + return nil +} + // ServeHTTP listens for incoming relay requests. It implements the respective // method of the http.Handler interface. It is called by http.ListenAndServe() // when synchronousRPCServer is used as an http.Handler with an http.Server. diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index 505d5dbd5..ea5848379 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -134,3 +134,22 @@ func (rel *relayMiner) ServePprof(ctx context.Context, addr string) error { return nil } + +func (rel *relayMiner) ServePing(ctx context.Context, ln net.Listener) error { + go func() { + if err := http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + rel.logger.Debug().Msg("pinging relay servers...") + + if errs := rel.relayerProxy.Ping(ctx); errs != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) + })); err != nil { + return + } + }() + + return nil +} diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index f7de39d39..930d4e11b 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -2,6 +2,9 @@ package relayer_test import ( "context" + "net" + "net/http" + "os" "testing" "time" @@ -57,3 +60,69 @@ func TestRelayMiner_StartAndStop(t *testing.T) { err = relayminer.Stop(ctx) require.NoError(t, err) } + +func TestRelayMiner_Ping(t *testing.T) { + srObs, _ := channel.NewObservable[*servicetypes.Relay]() + servedRelaysObs := relayer.RelaysObservable(srObs) + + mrObs, _ := channel.NewObservable[*relayer.MinedRelay]() + minedRelaysObs := relayer.MinedRelaysObservable(mrObs) + + ctx := polyzero.NewLogger().WithContext(context.Background()) + relayerProxyMock := testrelayer.NewMockOneTimeRelayerProxyWithPing( + ctx, t, + servedRelaysObs, + ) + + minerMock := testrelayer.NewMockOneTimeMiner( + ctx, t, + servedRelaysObs, + minedRelaysObs, + ) + + relayerSessionsManagerMock := testrelayer.NewMockOneTimeRelayerSessionsManager( + ctx, t, + minedRelaysObs, + ) + + deps := depinject.Supply( + relayerProxyMock, + minerMock, + relayerSessionsManagerMock, + ) + + relayminer, err := relayer.NewRelayMiner(ctx, deps) + require.NoError(t, err) + require.NotNil(t, relayminer) + + err = relayminer.Start(ctx) + require.NoError(t, err) + + time.Sleep(time.Millisecond) + + filename := "/tmp/relayerminer.ping.sock" + + ln, err := net.Listen("unix", filename) + require.NoError(t, err) + defer os.Remove(filename) + + err = relayminer.ServePing(ctx, ln) + require.NoError(t, err) + + time.Sleep(time.Millisecond) + + c := http.Client{ + Transport: &http.Transport{ + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + return net.Dial(ln.Addr().Network(), ln.Addr().String()) + }, + }, + } + require.NoError(t, err) + + _, err = c.Get("http://unix") + require.NoError(t, err) + + err = relayminer.Stop(ctx) + require.NoError(t, err) +} diff --git a/testutil/testrelayer/proxy.go b/testutil/testrelayer/proxy.go index a876ebec3..a65c003c2 100644 --- a/testutil/testrelayer/proxy.go +++ b/testutil/testrelayer/proxy.go @@ -33,5 +33,36 @@ func NewMockOneTimeRelayerProxy( ServedRelays(). Return(returnedRelaysObs). Times(1) + + return relayerProxyMock +} + +// NewMockOneTimeRelayerProxyWithPing creates a new mock RelayerProxy. This mock +// RelayerProxy will expect a call to ServedRelays with the given context, and +// when that call is made, returnedRelaysObs is returned. It also expects a call +// to Start, Ping, and Stop with the given context. +func NewMockOneTimeRelayerProxyWithPing( + ctx context.Context, + t *testing.T, + returnedRelaysObs relayer.RelaysObservable, +) *mockrelayer.MockRelayerProxy { + t.Helper() + + ctrl := gomock.NewController(t) + relayerProxyMock := mockrelayer.NewMockRelayerProxy(ctrl) + relayerProxyMock.EXPECT(). + Start(gomock.Eq(ctx)). + Times(1) + relayerProxyMock.EXPECT(). + Stop(gomock.Eq(ctx)). + Times(1) + relayerProxyMock.EXPECT(). + ServedRelays(). + Return(returnedRelaysObs). + Times(1) + relayerProxyMock.EXPECT(). + Ping(gomock.Eq(ctx)). + Times(1) + return relayerProxyMock } From ecbcb3e0a56087928883db0e432e3292ea6c88fd Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 19 Aug 2024 18:57:20 +0200 Subject: [PATCH 02/55] use dynamic slice in Ping error handling --- pkg/relayer/proxy/proxy.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/relayer/proxy/proxy.go b/pkg/relayer/proxy/proxy.go index 7bcd7cff2..564e85e82 100644 --- a/pkg/relayer/proxy/proxy.go +++ b/pkg/relayer/proxy/proxy.go @@ -213,14 +213,14 @@ func (rp *relayerProxy) validateConfig() error { // Ping tests the connectivity between all the managed relay servers and their respective backend URLs. func (rp *relayerProxy) Ping(ctx context.Context) []error { - errs := make([]error, len(rp.servers)) + var errs []error var i int for _, srv := range rp.servers { if err := srv.Ping(ctx); err != nil { rp.logger.Error().Err(err). Msg("an unexpected error occured while pinging backend URL") - errs[i] = err + errs = append(errs, err) } i++ From 54b79d1a2382de861d8651be9bff619c0ab045a0 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sat, 31 Aug 2024 12:12:54 +0200 Subject: [PATCH 03/55] relayer: add godoc to configuration yaml --- pkg/relayer/config/types.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/relayer/config/types.go b/pkg/relayer/config/types.go index fa47517b1..db6660805 100644 --- a/pkg/relayer/config/types.go +++ b/pkg/relayer/config/types.go @@ -27,6 +27,7 @@ type YAMLRelayMinerConfig struct { Ping YAMLRelayMinerPingConfig `yaml:"ping"` } +// YAMLRelayMinerPingConfig represents the configuration to expose a ping server. type YAMLRelayMinerPingConfig struct { Enabled bool `yaml:"enabled"` Addr string `yaml:"addr"` @@ -92,6 +93,8 @@ type RelayMinerConfig struct { Ping *RelayMinerPingConfig } +// RelayMinerPingConfig is the structure resulting from parsing the ping +// server configuration. type RelayMinerPingConfig struct { Enabled bool Addr string From 7bd3223137a69c40407d2e5f58947b6186dfc2c4 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sat, 31 Aug 2024 12:21:43 +0200 Subject: [PATCH 04/55] proxy: add comment explaining application logic --- pkg/relayer/proxy/proxy.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/relayer/proxy/proxy.go b/pkg/relayer/proxy/proxy.go index 564e85e82..371873f31 100644 --- a/pkg/relayer/proxy/proxy.go +++ b/pkg/relayer/proxy/proxy.go @@ -166,6 +166,8 @@ func (rp *relayerProxy) Start(ctx context.Context) error { for _, relayServer := range rp.servers { server := relayServer // create a new variable scoped to the anonymous function + // Ensure that each backing data node responds to a ping request + // (at least) before continuing operation. if err := server.Ping(ctx); err != nil { return err } From 023497822002b1b292cd311a483a4c0d3419d67e Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sat, 31 Aug 2024 12:27:06 +0200 Subject: [PATCH 05/55] relayer: change Ping to PingAll in relayproxy interface --- pkg/relayer/interface.go | 4 ++-- pkg/relayer/proxy/proxy.go | 4 ++-- pkg/relayer/proxy/proxy_test.go | 2 +- pkg/relayer/relayminer.go | 2 +- testutil/testrelayer/proxy.go | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/relayer/interface.go b/pkg/relayer/interface.go index 586357c82..310a8692d 100644 --- a/pkg/relayer/interface.go +++ b/pkg/relayer/interface.go @@ -74,8 +74,8 @@ type RelayerProxy interface { // that should not be responsible for signing relay responses. SignRelayResponse(relayResponse *servicetypes.RelayResponse, supplierOperatorAddr string) error - // Ping tests the connectivity between all the managed relay servers and their respective backend URLs. - Ping(ctx context.Context) []error + // PingAll tests the connectivity between all the managed relay servers and their respective backend URLs. + PingAll(ctx context.Context) []error } type RelayerProxyOption func(RelayerProxy) diff --git a/pkg/relayer/proxy/proxy.go b/pkg/relayer/proxy/proxy.go index 371873f31..43588104f 100644 --- a/pkg/relayer/proxy/proxy.go +++ b/pkg/relayer/proxy/proxy.go @@ -213,8 +213,8 @@ func (rp *relayerProxy) validateConfig() error { return nil } -// Ping tests the connectivity between all the managed relay servers and their respective backend URLs. -func (rp *relayerProxy) Ping(ctx context.Context) []error { +// PingAll tests the connectivity between all the managed relay servers and their respective backend URLs. +func (rp *relayerProxy) PingAll(ctx context.Context) []error { var errs []error var i int diff --git a/pkg/relayer/proxy/proxy_test.go b/pkg/relayer/proxy/proxy_test.go index 774757592..330656b33 100644 --- a/pkg/relayer/proxy/proxy_test.go +++ b/pkg/relayer/proxy/proxy_test.go @@ -151,7 +151,7 @@ func TestRelayerProxy_StartAndStop(t *testing.T) { // Block so relayerProxy has sufficient time to start time.Sleep(100 * time.Millisecond) - errs := rp.Ping(ctx) + errs := rp.PingAll(ctx) for _, err := range errs { require.NoError(t, err) } diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index ea5848379..40f9886b2 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -140,7 +140,7 @@ func (rel *relayMiner) ServePing(ctx context.Context, ln net.Listener) error { if err := http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { rel.logger.Debug().Msg("pinging relay servers...") - if errs := rel.relayerProxy.Ping(ctx); errs != nil { + if errs := rel.relayerProxy.PingAll(ctx); errs != nil { w.WriteHeader(http.StatusInternalServerError) return } diff --git a/testutil/testrelayer/proxy.go b/testutil/testrelayer/proxy.go index a65c003c2..719bd2204 100644 --- a/testutil/testrelayer/proxy.go +++ b/testutil/testrelayer/proxy.go @@ -61,7 +61,7 @@ func NewMockOneTimeRelayerProxyWithPing( Return(returnedRelaysObs). Times(1) relayerProxyMock.EXPECT(). - Ping(gomock.Eq(ctx)). + PingAll(gomock.Eq(ctx)). Times(1) return relayerProxyMock From affc9373cae9d716fea9c82ba8e2ad9135f3ed2d Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sat, 31 Aug 2024 12:35:24 +0200 Subject: [PATCH 06/55] proxy: cleanup unused code --- pkg/relayer/proxy/proxy.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/relayer/proxy/proxy.go b/pkg/relayer/proxy/proxy.go index 43588104f..dde13e17d 100644 --- a/pkg/relayer/proxy/proxy.go +++ b/pkg/relayer/proxy/proxy.go @@ -217,15 +217,12 @@ func (rp *relayerProxy) validateConfig() error { func (rp *relayerProxy) PingAll(ctx context.Context) []error { var errs []error - var i int for _, srv := range rp.servers { if err := srv.Ping(ctx); err != nil { rp.logger.Error().Err(err). Msg("an unexpected error occured while pinging backend URL") errs = append(errs, err) } - - i++ } if len(errs) > 0 { From 9ddc62a692b6eee61e17c89310edfcc513033b8c Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sat, 31 Aug 2024 12:39:16 +0200 Subject: [PATCH 07/55] relayer: add godoc explaining ping http serve method --- pkg/relayer/relayminer.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index 40f9886b2..249d4f330 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -135,7 +135,13 @@ func (rel *relayMiner) ServePprof(ctx context.Context, addr string) error { return nil } +// ServePing exposes ping HTTP server to check the reachability between the +// relay miner and its dependencies (Ex: relay server and their respective +// backend URLs). func (rel *relayMiner) ServePing(ctx context.Context, ln net.Listener) error { + // Start a long-lived goroutine that starts an HTTP server responding to + // ping requests. A single ping request on the relay server broadcasts a + // ping to all backing services/data nodes. go func() { if err := http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { rel.logger.Debug().Msg("pinging relay servers...") From 8395970a731596a6c1ebe2c2e08c27a50df1be43 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sat, 31 Aug 2024 12:42:43 +0200 Subject: [PATCH 08/55] relayer: remove blank line --- pkg/relayer/proxy/synchronous.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/relayer/proxy/synchronous.go b/pkg/relayer/proxy/synchronous.go index 77761641d..a1ef040a9 100644 --- a/pkg/relayer/proxy/synchronous.go +++ b/pkg/relayer/proxy/synchronous.go @@ -112,7 +112,6 @@ func (sync *synchronousRPCServer) Ping(ctx context.Context) error { if resp.StatusCode >= http.StatusInternalServerError { return errors.New("ping failed") } - } return nil From 2df64792d1de48ee44f01524357dda082a676591 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Wed, 25 Sep 2024 12:13:46 +0200 Subject: [PATCH 09/55] localnet: add ping helpers for relayminers + logic to define suppliers based on localnet config --- Makefile | 779 +++++++++++++++++- Tiltfile | 22 +- .../kubernetes/values-relayminer-1-all.yaml | 20 + .../values-relayminer-1-ollama.yaml | 14 + .../kubernetes/values-relayminer-1-rest.yaml | 14 + localnet/kubernetes/values-relayminer-1.yaml | 12 - .../values-relayminer-2-ollama.yaml | 14 + localnet/kubernetes/values-relayminer-2.yaml | 6 - .../values-relayminer-3-ollama.yaml | 14 + localnet/kubernetes/values-relayminer-3.yaml | 6 - .../kubernetes/values-relayminer-common.yaml | 3 + 11 files changed, 845 insertions(+), 59 deletions(-) create mode 100644 localnet/kubernetes/values-relayminer-1-all.yaml create mode 100644 localnet/kubernetes/values-relayminer-1-ollama.yaml create mode 100644 localnet/kubernetes/values-relayminer-1-rest.yaml create mode 100644 localnet/kubernetes/values-relayminer-2-ollama.yaml create mode 100644 localnet/kubernetes/values-relayminer-3-ollama.yaml diff --git a/Makefile b/Makefile index 147a86b2b..66caf8581 100644 --- a/Makefile +++ b/Makefile @@ -80,39 +80,10 @@ endif .PHONY: install_ci_deps install_ci_deps: ## Installs `mockgen` and other go tools go install "github.com/golang/mock/mockgen@v1.6.0" && mockgen --version - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.60.3 && golangci-lint --version + go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.1 && golangci-lint --version go install golang.org/x/tools/cmd/goimports@latest go install github.com/mikefarah/yq/v4@latest -.PHONY: install_cosmovisor -install_cosmovisor: ## Installs `cosmovisor` - go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@v1.6.0 && cosmovisor version --cosmovisor-only - -.PHONY: cosmovisor_cross_compile -cosmovisor_cross_compile: # Installs multiple cosmovisor binaries for different platforms (used by Dockerfile.release) - @COSMOVISOR_VERSION="v1.6.0"; \ - PLATFORMS="linux/amd64 linux/arm64"; \ - mkdir -p ./tmp; \ - echo "Fetching Cosmovisor source..."; \ - temp_dir=$$(mktemp -d); \ - cd $$temp_dir; \ - go mod init temp; \ - go get cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@$$COSMOVISOR_VERSION; \ - for platform in $$PLATFORMS; do \ - OS=$${platform%/*}; \ - ARCH=$${platform#*/}; \ - echo "Compiling for $$OS/$$ARCH..."; \ - GOOS=$$OS GOARCH=$$ARCH go build -o $(CURDIR)/tmp/cosmovisor-$$OS-$$ARCH cosmossdk.io/tools/cosmovisor/cmd/cosmovisor; \ - done; \ - cd $(CURDIR); \ - rm -rf $$temp_dir; \ - echo "Compilation complete. Binaries are in ./tmp/"; \ - ls -l ./tmp/cosmovisor-* - -.PHONY: cosmovisor_clean -cosmovisor_clean: - rm -f ./tmp/cosmovisor-* - ######################## ### Makefile Helpers ### ######################## @@ -131,6 +102,167 @@ list: ## List all make targets help: ## Prints all the targets in all the Makefiles @grep -h -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-60s\033[0m %s\n", $$1, $$2}' +############## +### Checks ### +############## + +# TODO_DOCUMENT: All of the `check_` helpers can be installed differently depending +# on the user's OS and environment. +# NB: For mac users, you may need to install with the proper linkers: https://github.com/golang/go/issues/65940 + +.PHONY: check_go_version +# Internal helper target - check go version +check_go_version: + @# Extract the version number from the `go version` command. + @GO_VERSION=$$(go version | cut -d " " -f 3 | cut -c 3-) && \ + MAJOR_VERSION=$$(echo $$GO_VERSION | cut -d "." -f 1) && \ + MINOR_VERSION=$$(echo $$GO_VERSION | cut -d "." -f 2) && \ + \ + if [ "$$MAJOR_VERSION" -ne 1 ] || [ "$$MINOR_VERSION" -le 20 ] ; then \ + echo "Invalid Go version. Expected 1.21.x or newer but found $$GO_VERSION"; \ + exit 1; \ + fi + +.PHONY: check_ignite_version +# Internal helper target - check ignite version +check_ignite_version: + @version=$$(ignite version 2>/dev/null | grep 'Ignite CLI version:' | awk '{print $$4}') ; \ + if [ "$$(printf "v28\n$$version" | sort -V | head -n1)" != "v28" ]; then \ + echo "Error: Version $$version is less than v28. Exiting with error." ; \ + exit 1 ; \ + fi + +.PHONY: check_mockgen +# Internal helper target- Check if mockgen is installed +check_mockgen: + { \ + if ( ! ( command -v mockgen >/dev/null )); then \ + echo "Seems like you don't have `mockgen` installed. Please visit https://github.com/golang/mock#installation and follow the instructions to install `mockgen` before continuing"; \ + exit 1; \ + fi; \ + } + + +.PHONY: check_act +# Internal helper target - check if `act` is installed +check_act: + { \ + if ( ! ( command -v act >/dev/null )); then \ + echo "Seems like you don't have `act` installed. Please visit https://github.com/nektos/act before continuing"; \ + exit 1; \ + fi; \ + } + +.PHONY: check_gh +# Internal helper target - check if `gh` is installed +check_gh: + { \ + if ( ! ( command -v gh >/dev/null )); then \ + echo "Seems like you don't have `gh` installed. Please visit https://cli.github.com/ before continuing"; \ + exit 1; \ + fi; \ + } + +.PHONY: check_docker +# Internal helper target - check if docker is installed +check_docker: + { \ + if ( ! ( command -v docker >/dev/null && (docker compose version >/dev/null || command -v docker-compose >/dev/null) )); then \ + echo "Seems like you don't have Docker or docker-compose installed. Make sure you review build/localnet/README.md and docs/development/README.md before continuing"; \ + exit 1; \ + fi; \ + } +.PHONY: check_kind +# Internal helper target - check if kind is installed +check_kind: + @if ! command -v kind >/dev/null 2>&1; then \ + echo "kind is not installed. Make sure you review build/localnet/README.md and docs/development/README.md before continuing"; \ + exit 1; \ + fi + +.PHONY: check_docker_ps + ## Internal helper target - checks if Docker is running +check_docker_ps: check_docker + @echo "Checking if Docker is running..." + @docker ps > /dev/null 2>&1 || (echo "Docker is not running. Please start Docker and try again."; exit 1) + +.PHONY: check_kind_context +## Internal helper target - checks if the kind-kind context exists and is set +check_kind_context: check_kind + @if ! kubectl config get-contexts | grep -q 'kind-kind'; then \ + echo "kind-kind context does not exist. Please create it or switch to it."; \ + exit 1; \ + fi + @if ! kubectl config current-context | grep -q 'kind-kind'; then \ + echo "kind-kind context is not currently set. Use 'kubectl config use-context kind-kind' to set it."; \ + exit 1; \ + fi + + +.PHONY: check_godoc +# Internal helper target - check if godoc is installed +check_godoc: + { \ + if ( ! ( command -v godoc >/dev/null )); then \ + echo "Seems like you don't have godoc installed. Make sure you install it via 'go install golang.org/x/tools/cmd/godoc@latest' before continuing"; \ + exit 1; \ + fi; \ + } + +.PHONY: check_npm +# Internal helper target - check if npm is installed +check_npm: + { \ + if ( ! ( command -v npm >/dev/null )); then \ + echo "Seems like you don't have npm installed. Make sure you install it before continuing"; \ + exit 1; \ + fi; \ + } + +.PHONY: check_jq +# Internal helper target - check if jq is installed +check_jq: + { \ + if ( ! ( command -v jq >/dev/null )); then \ + echo "Seems like you don't have jq installed. Make sure you install it before continuing"; \ + exit 1; \ + fi; \ + } + +.PHONY: check_yq +# Internal helper target - check if `yq` is installed +check_yq: + { \ + if ( ! ( command -v yq >/dev/null )); then \ + echo "Seems like you don't have `yq` installed. Make sure you install it before continuing"; \ + exit 1; \ + fi; \ + } + +.PHONY: check_node +# Internal helper target - check if node is installed +check_node: + { \ + if ( ! ( command -v node >/dev/null )); then \ + echo "Seems like you don't have node installed. Make sure you install it before continuing"; \ + exit 1; \ + fi; \ + } + +.PHONY: check_proto_unstable_marshalers +check_proto_unstable_marshalers: ## Check that all protobuf files have the `stable_marshalers_all` option set to true. + go run ./tools/scripts/protocheck/cmd unstable + +.PHONY: fix_proto_unstable_marshalers +fix_proto_unstable_marshalers: ## Ensure the `stable_marshaler_all` option is present on all protobuf files. + go run ./tools/scripts/protocheck/cmd unstable --fix + ${MAKE} proto_regen + + +.PHONY: warn_destructive +warn_destructive: ## Print WARNING to the user + @echo "This is a destructive action that will affect docker resources outside the scope of this repo!" + ####################### ### Proto Helpers #### ####################### @@ -181,6 +313,75 @@ docker_wipe: check_docker warn_destructive prompt_user ## [WARNING] Remove all t docker images -q | xargs -r -I {} docker rmi {} docker volume ls -q | xargs -r -I {} docker volume rm {} +######################## +### Localnet Helpers ### +######################## + +.PHONY: localnet_up +localnet_up: check_docker_ps check_kind_context proto_regen localnet_regenesis ## Starts up a clean localnet + tilt up + +.PHONY: localnet_up_quick +localnet_up_quick: check_docker_ps check_kind_context ## Starts up a localnet without regenerating fixtures + tilt up + +.PHONY: localnet_down +localnet_down: ## Delete resources created by localnet + tilt down + +.PHONY: localnet_regenesis +localnet_regenesis: check_yq warn_message_acc_initialize_pubkeys ## Regenerate the localnet genesis file +# NOTE: intentionally not using --home flag to avoid overwriting the test keyring + @echo "Initializing chain..." + @set -e + @ignite chain init --skip-proto + AUTH_CONTENT=$$(cat ./tools/scripts/authz/dao_genesis_authorizations.json | jq -r tostring); \ + $(SED) -i -E 's!^(\s*)"authorization": (\[\]|null)!\1"authorization": '$$AUTH_CONTENT'!' ${HOME}/.poktroll/config/genesis.json; + + @cp -r ${HOME}/.poktroll/keyring-test $(POKTROLLD_HOME) + @cp -r ${HOME}/.poktroll/config $(POKTROLLD_HOME)/ + +.PHONE: localnet_relayminer1_ping +localnet_relayminer1_ping: + @echo "Pinging relayminer 1..." + @curl -X GET localhost:7001 || (echo "Failed to ping relayminer1. Make sure your localnet environment or your relayminer pod is up and running"; exit 1) + @echo "OK" + +.PHONE: localnet_relayminer2_ping +localnet_relayminer2_ping: + @echo "Pinging relayminer 2..." + @curl -X GET localhost:7002 || (echo "Failed to ping relayminer2. Make sure your localnet environment or your relayminer pod is up and running"; exit 1) + @echo "OK" + +.PHONE: localnet_relayminer3_ping +localnet_relayminer3_ping: + @echo "Pinging relayminer 3..." + @curl -X GET localhost:7003 || (echo "Failed to ping relayminer3. Make sure your localnet environment or your relayminer pod is up and running"; exit 1) + @echo "OK" + +.PHONY: send_relay_sovereign_app_JSONRPC +send_relay_sovereign_app_JSONRPC: # Send a JSONRPC relay through the AppGateServer as a sovereign application + curl -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ + $(APPGATE_SERVER)/anvil + +.PHONY: send_relay_delegating_app_JSONRPC +send_relay_delegating_app_JSONRPC: # Send a relay through the gateway as an application that's delegating to this gateway + @appAddr=$$(poktrolld keys show app1 -a) && \ + curl -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ + $(GATEWAY_URL)/anvil?applicationAddr=$$appAddr + +.PHONY: send_relay_sovereign_app_REST +send_relay_sovereign_app_REST: # Send a REST relay through the AppGateServer as a sovereign application + curl -X POST -H "Content-Type: application/json" \ + --data '{"model": "qwen:0.5b", "stream": false, "messages": [{"role": "user", "content":"count from 1 to 10"}]}' \ + $(APPGATE_SERVER)/ollama/api/chat + +.PHONY: cosmovisor_start_node +cosmovisor_start_node: # Starts the node using cosmovisor that waits for an upgrade plan + bash tools/scripts/upgrades/cosmovisor-start-node.sh + ############### ### Linting ### ############### @@ -192,6 +393,96 @@ go_lint: ## Run all go linters go_imports: check_go_version ## Run goimports on all go files go run ./tools/scripts/goimports +############# +### Tests ### +############# + +.PHONY: test_e2e_env +test_e2e_env: warn_message_acc_initialize_pubkeys ## Setup the default env vars for E2E tests + export POCKET_NODE=$(POCKET_NODE) && \ + export APPGATE_SERVER=$(APPGATE_SERVER) && \ + export POKTROLLD_HOME=../../$(POKTROLLD_HOME) + +.PHONY: test_e2e +test_e2e: test_e2e_env ## Run all E2E tests + go test -count=1 -v ./e2e/tests/... -tags=e2e,test + +.PHONY: test_e2e_relay +test_e2e_relay: test_e2e_env ## Run only the E2E suite that exercises the relay life-cycle + go test -v ./e2e/tests/... -tags=e2e,test --features-path=relay.feature + +.PHONY: test_e2e_app +test_e2e_app: test_e2e_env ## Run only the E2E suite that exercises the application life-cycle + go test -v ./e2e/tests/... -tags=e2e,test --features-path=stake_app.feature + +.PHONY: test_e2e_supplier +test_e2e_supplier: test_e2e_env ## Run only the E2E suite that exercises the supplier life-cycle + go test -v ./e2e/tests/... -tags=e2e,test --features-path=stake_supplier.feature + +.PHONY: test_e2e_gateway +test_e2e_gateway: test_e2e_env ## Run only the E2E suite that exercises the gateway life-cycle + go test -v ./e2e/tests/... -tags=e2e,test --features-path=stake_gateway.feature + +.PHONY: test_e2e_session +test_e2e_session: test_e2e_env ## Run only the E2E suite that exercises the session (i.e. claim/proof) life-cycle + go test -v ./e2e/tests/... -tags=e2e,test --features-path=session.feature + +.PHONY: test_e2e_tokenomics +test_e2e_tokenomics: test_e2e_env ## Run only the E2E suite that exercises the session & tokenomics settlement + go test -v ./e2e/tests/... -tags=e2e,test --features-path=0_settlement.feature + +.PHONY: test_e2e_params +test_e2e_params: test_e2e_env ## Run only the E2E suite that exercises parameter updates for all modules + go test -v ./e2e/tests/... -tags=e2e,test --features-path=update_params.feature + +.PHONY: test_load_relays_stress_custom +test_load_relays_stress_custom: ## Run the stress test for E2E relays using custom manifest. "loadtest_manifest_example.yaml" manifest is used by default. Set `LOAD_TEST_CUSTOM_MANIFEST` environment variable to use the different manifest. + go test -v -count=1 ./load-testing/tests/... \ + -tags=load,test -run LoadRelays --log-level=debug --timeout=30m \ + --manifest ./load-testing/$(LOAD_TEST_CUSTOM_MANIFEST) + +.PHONY: test_load_relays_stress_localnet +test_load_relays_stress_localnet: test_e2e_env warn_message_local_stress_test ## Run the stress test for E2E relays on LocalNet. + go test -v -count=1 ./load-testing/tests/... \ + -tags=load,test -run LoadRelays --log-level=debug --timeout=30m \ + --manifest ./load-testing/loadtest_manifest_localnet.yaml + +.PHONY: test_load_relays_stress_localnet_single_supplier +test_load_relays_stress_localnet_single_supplier: test_e2e_env warn_message_local_stress_test ## Run the stress test for E2E relays on LocalNet using exclusively one supplier. + go test -v -count=1 ./load-testing/tests/... \ + -tags=load,test -run TestLoadRelaysSingleSupplier --log-level=debug --timeout=30m \ + --manifest ./load-testing/loadtest_manifest_localnet_single_supplier.yaml + +.PHONY: test_verbose +test_verbose: check_go_version ## Run all go tests verbosely + go test -count=1 -v -race -tags test ./... + +# NB: buildmode=pie is necessary to avoid linker errors on macOS. +# It is not compatible with `-race`, which is why it's omitted here. +# See ref for more details: https://github.com/golang/go/issues/54482#issuecomment-1251124908 +.PHONY: test_all +test_all: warn_flaky_tests check_go_version ## Run all go tests showing detailed output only on failures + go test -count=1 -buildmode=pie -tags test ./... + +.PHONY: test_all_with_integration +test_all_with_integration: check_go_version ## Run all go tests, including those with the integration + go test -count=1 -v -race -tags test,integration ./... + +# We are explicitly using an env variable rather than a build tag to keep flaky +# tests in line with non flaky tests and use it as a way to easily turn them +# on and off without maintaining extra files. +.PHONY: test_all_with_integration_and_flaky +test_all_with_integration_and_flaky: check_go_version ## Run all go tests, including those with the integration and flaky tests + INCLUDE_FLAKY_TESTS=true go test -count=1 -v -race -tags test,integration ./... + +.PHONY: test_integration +test_integration: check_go_version ## Run only the in-memory integration "unit" tests + go test -count=1 -v -race -tags test,integration ./tests/integration/... + +.PHONY: itest +itest: check_go_version ## Run tests iteratively (see usage for more) + ./tools/scripts/itest.sh $(filter-out $@,$(MAKECMDGOALS)) + .PHONY: go_mockgen go_mockgen: ## Use `mockgen` to generate mocks used for testing purposes of all the modules. find . -name "*_mock.go" | xargs --no-run-if-empty rm @@ -218,6 +509,278 @@ go_develop: check_ignite_version proto_regen go_mockgen ## Generate protos and m .PHONY: go_develop_and_test go_develop_and_test: go_develop test_all ## Generate protos, mocks and run all tests +############# +### TODOS ### +############# + +# How do I use TODOs? +# 1. : ; +# e.g. TODO_HACK: This is a hack, we need to fix it later +# 2. If there's a specific issue, or specific person, add that in paranthesiss +# e.g. TODO(@Olshansk): Automatically link to the Github user https://github.com/olshansk +# e.g. TODO_INVESTIGATE(#420): Automatically link this to github issue https://github.com/pokt-network/poktroll/issues/420 +# e.g. TODO_DISCUSS(@Olshansk, #420): Specific individual should tend to the action item in the specific ticket +# e.g. TODO_CLEANUP(core): This is not tied to an issue, or a person, but should only be done by the core team. +# e.g. TODO_CLEANUP: This is not tied to an issue, or a person, and can be done by the core team or external contributors. +# 3. Feel free to add additional keywords to the list above. + +# Inspired by @goldinguy_ in this post: https://goldin.io/blog/stop-using-todo ### +# TODO - General Purpose catch-all. +# TODO_COMMUNITY - A TODO that may be a candidate for outsourcing to the community. +# TODO_DECIDE - A TODO indicating we need to make a decision and document it using an ADR in the future; https://github.com/pokt-network/pocket-network-protocol/tree/main/ADRs +# TODO_TECHDEBT - Not a great implementation, but we need to fix it later. +# TODO_BLOCKER - BEFORE MAINNET. Similar to TECHDEBT, but of higher priority, urgency & risk prior to the next release +# TODO_QOL - AFTER MAINNET. Similar to TECHDEBT, but of lower priority. Doesn't deserve a GitHub Issue but will improve everyone's life. +# TODO_IMPROVE - A nice to have, but not a priority. It's okay if we never get to this. +# TODO_OPTIMIZE - An opportunity for performance improvement if/when it's necessary +# TODO_DISCUSS - Probably requires a lengthy offline discussion to understand next steps. +# TODO_INCOMPLETE - A change which was out of scope of a specific PR but needed to be documented. +# TODO_INVESTIGATE - TBD what was going on, but needed to continue moving and not get distracted. +# TODO_CLEANUP - Like TECHDEBT, but not as bad. It's okay if we never get to this. +# TODO_HACK - Like TECHDEBT, but much worse. This needs to be prioritized +# TODO_REFACTOR - Similar to TECHDEBT, but will require a substantial rewrite and change across the codebase +# TODO_CONSIDERATION - A comment that involves extra work but was thoughts / considered as part of some implementation +# TODO_CONSOLIDATE - We likely have similar implementations/types of the same thing, and we should consolidate them. +# TODO_ADDTEST / TODO_TEST - Add more tests for a specific code section +# TODO_FLAKY - Signals that the test is flaky and we are aware of it. Provide an explanation if you know why. +# TODO_DEPRECATE - Code that should be removed in the future +# TODO_RESEARCH - A non-trivial action item that requires deep research and investigation being next steps can be taken +# TODO_DOCUMENT - A comment that involves the creation of a README or other documentation +# TODO_BUG - There is a known existing bug in this code +# TODO_NB - An important note to reference later +# TODO_DISCUSS_IN_THIS_COMMIT - SHOULD NEVER BE COMMITTED TO MASTER. It is a way for the reviewer of a PR to start / reply to a discussion. +# TODO_IN_THIS_COMMIT - SHOULD NEVER BE COMMITTED TO MASTER. It is a way to start the review process while non-critical changes are still in progress + + +# Define shared variable for the exclude parameters +EXCLUDE_GREP = --exclude-dir={.git,vendor,./docusaurus,.vscode,.idea} --exclude={Makefile,reviewdog.yml,*.pb.go,*.pulsar.go} + +.PHONY: todo_list +todo_list: ## List all the TODOs in the project (excludes vendor and prototype directories) + grep -r $(EXCLUDE_GREP) TODO . | grep -v 'TODO()' + +.PHONY: todo_count +todo_count: ## Print a count of all the TODOs in the project + grep -r $(EXCLUDE_GREP) TODO . | grep -v 'TODO()' | wc -l + +.PHONY: todo_this_commit +todo_this_commit: ## List all the TODOs needed to be done in this commit + grep -r $(EXCLUDE_GREP) TODO_IN_THIS .| grep -v 'TODO()' + + +#################### +### Gateways ### +#################### + +.PHONY: gateway_list +gateway_list: ## List all the staked gateways + poktrolld --home=$(POKTROLLD_HOME) q gateway list-gateway --node $(POCKET_NODE) + +.PHONY: gateway_stake +gateway_stake: ## Stake tokens for the gateway specified (must specify the gateway env var) + poktrolld --home=$(POKTROLLD_HOME) tx gateway stake-gateway -y --config $(POKTROLLD_HOME)/config/$(STAKE) --keyring-backend test --from $(GATEWAY) --node $(POCKET_NODE) + +.PHONY: gateway1_stake +gateway1_stake: ## Stake gateway1 + GATEWAY=gateway1 STAKE=gateway1_stake_config.yaml make gateway_stake + +.PHONY: gateway2_stake +gateway2_stake: ## Stake gateway2 + GATEWAY=gateway2 STAKE=gateway2_stake_config.yaml make gateway_stake + +.PHONY: gateway3_stake +gateway3_stake: ## Stake gateway3 + GATEWAY=gateway3 STAKE=gateway3_stake_config.yaml make gateway_stake + +.PHONY: gateway_unstake +gateway_unstake: ## Unstake an gateway (must specify the GATEWAY env var) + poktrolld --home=$(POKTROLLD_HOME) tx gateway unstake-gateway -y --keyring-backend test --from $(GATEWAY) --node $(POCKET_NODE) + +.PHONY: gateway1_unstake +gateway1_unstake: ## Unstake gateway1 + GATEWAY=gateway1 make gateway_unstake + +.PHONY: gateway2_unstake +gateway2_unstake: ## Unstake gateway2 + GATEWAY=gateway2 make gateway_unstake + +.PHONY: gateway3_unstake +gateway3_unstake: ## Unstake gateway3 + GATEWAY=gateway3 make gateway_unstake + +#################### +### Applications ### +#################### + +.PHONY: app_list +app_list: ## List all the staked applications + poktrolld --home=$(POKTROLLD_HOME) q application list-application --node $(POCKET_NODE) + +.PHONY: app_stake +app_stake: ## Stake tokens for the application specified (must specify the APP and SERVICES env vars) + poktrolld --home=$(POKTROLLD_HOME) tx application stake-application -y --config $(POKTROLLD_HOME)/config/$(SERVICES) --keyring-backend test --from $(APP) --node $(POCKET_NODE) + +.PHONY: app1_stake +app1_stake: ## Stake app1 (also staked in genesis) + APP=app1 SERVICES=application1_stake_config.yaml make app_stake + +.PHONY: app2_stake +app2_stake: ## Stake app2 + APP=app2 SERVICES=application2_stake_config.yaml make app_stake + +.PHONY: app3_stake +app3_stake: ## Stake app3 + APP=app3 SERVICES=application3_stake_config.yaml make app_stake + +.PHONY: app_unstake +app_unstake: ## Unstake an application (must specify the APP env var) + poktrolld --home=$(POKTROLLD_HOME) tx application unstake-application -y --keyring-backend test --from $(APP) --node $(POCKET_NODE) + +.PHONY: app1_unstake +app1_unstake: ## Unstake app1 + APP=app1 make app_unstake + +.PHONY: app2_unstake +app2_unstake: ## Unstake app2 + APP=app2 make app_unstake + +.PHONY: app3_unstake +app3_unstake: ## Unstake app3 + APP=app3 make app_unstake + +.PHONY: app_delegate +app_delegate: ## Delegate trust to a gateway (must specify the APP and GATEWAY_ADDR env vars). Requires the app to be staked + poktrolld --home=$(POKTROLLD_HOME) tx application delegate-to-gateway $(GATEWAY_ADDR) --keyring-backend test --from $(APP) --node $(POCKET_NODE) + +.PHONY: app1_delegate_gateway1 +app1_delegate_gateway1: ## Delegate trust to gateway1 + GATEWAY1=$$(make poktrolld_addr ACC_NAME=gateway1) && \ + APP=app1 GATEWAY_ADDR=$$GATEWAY1 make app_delegate + +.PHONY: app2_delegate_gateway2 +app2_delegate_gateway2: ## Delegate trust to gateway2 + GATEWAY2=$$(make poktrolld_addr ACC_NAME=gateway2) && \ + APP=app2 GATEWAY_ADDR=$$GATEWAY2 make app_delegate + +.PHONY: app3_delegate_gateway3 +app3_delegate_gateway3: ## Delegate trust to gateway3 + GATEWAY3=$$(make poktrolld_addr ACC_NAME=gateway3) && \ + APP=app3 GATEWAY_ADDR=$$GATEWAY3 make app_delegate + +.PHONY: app_undelegate +app_undelegate: ## Undelegate trust to a gateway (must specify the APP and GATEWAY_ADDR env vars). Requires the app to be staked + poktrolld --home=$(POKTROLLD_HOME) tx application undelegate-from-gateway $(GATEWAY_ADDR) --keyring-backend test --from $(APP) --node $(POCKET_NODE) + +.PHONY: app1_undelegate_gateway1 +app1_undelegate_gateway1: ## Undelegate trust to gateway1 + GATEWAY1=$$(make poktrolld_addr ACC_NAME=gateway1) && \ + APP=app1 GATEWAY_ADDR=$$GATEWAY1 make app_undelegate + +.PHONY: app2_undelegate_gateway2 +app2_undelegate_gateway2: ## Undelegate trust to gateway2 + GATEWAY2=$$(make poktrolld_addr ACC_NAME=gateway2) && \ + APP=app2 GATEWAY_ADDR=$$GATEWAY2 make app_undelegate + +.PHONY: app3_undelegate_gateway3 +app3_undelegate_gateway3: ## Undelegate trust to gateway3 + GATEWAY3=$$(make poktrolld_addr ACC_NAME=gateway3) && \ + APP=app3 GATEWAY_ADDR=$$GATEWAY3 make app_undelegate + +################# +### Suppliers ### +################# + +.PHONY: supplier_list +supplier_list: ## List all the staked supplier + poktrolld --home=$(POKTROLLD_HOME) q supplier list-supplier --node $(POCKET_NODE) + +.PHONY: supplier_stake +supplier_stake: ## Stake tokens for the supplier specified (must specify the SUPPLIER and SUPPLIER_CONFIG env vars) + poktrolld --home=$(POKTROLLD_HOME) tx supplier stake-supplier -y --config $(POKTROLLD_HOME)/config/$(SERVICES) --keyring-backend test --from $(SUPPLIER) --node $(POCKET_NODE) + +.PHONY: supplier1_stake +supplier1_stake: ## Stake supplier1 (also staked in genesis) + SUPPLIER=supplier1 SERVICES=supplier1_stake_config.yaml make supplier_stake + +.PHONY: supplier2_stake +supplier2_stake: ## Stake supplier2 + SUPPLIER=supplier2 SERVICES=supplier2_stake_config.yaml make supplier_stake + +.PHONY: supplier3_stake +supplier3_stake: ## Stake supplier3 + SUPPLIER=supplier3 SERVICES=supplier3_stake_config.yaml make supplier_stake + +.PHONY: supplier_unstake +supplier_unstake: ## Unstake an supplier (must specify the SUPPLIER env var) + poktrolld --home=$(POKTROLLD_HOME) tx supplier unstake-supplier $(SUPPLIER) --keyring-backend test --from $(SUPPLIER) --node $(POCKET_NODE) + +.PHONY: supplier1_unstake +supplier1_unstake: ## Unstake supplier1 + SUPPLIER=supplier1 make supplier_unstake + +.PHONY: supplier2_unstake +supplier2_unstake: ## Unstake supplier2 + SUPPLIER=supplier2 make supplier_unstake + +.PHONY: supplier3_unstake +supplier3_unstake: ## Unstake supplier3 + SUPPLIER=supplier3 make supplier_unstake + +############### +### Session ### +############### + +.PHONY: get_session +get_session: ## Retrieve the session given the following env vars: (APP_ADDR, SVC, HEIGHT) + poktrolld --home=$(POKTROLLD_HOME) q session get-session $(APP) $(SVC) $(HEIGHT) --node $(POCKET_NODE) + +.PHONY: get_session_app1_anvil +get_session_app1_anvil: ## Retrieve the session for (app1, anvil, latest_height) + APP1=$$(make poktrolld_addr ACC_NAME=app1) && \ + APP=$$APP1 SVC=anvil HEIGHT=0 make get_session + +.PHONY: get_session_app2_anvil +get_session_app2_anvil: ## Retrieve the session for (app2, anvil, latest_height) + APP2=$$(make poktrolld_addr ACC_NAME=app2) && \ + APP=$$APP2 SVC=anvil HEIGHT=0 make get_session + +.PHONY: get_session_app3_anvil +get_session_app3_anvil: ## Retrieve the session for (app3, anvil, latest_height) + APP3=$$(make poktrolld_addr ACC_NAME=app3) && \ + APP=$$APP3 SVC=anvil HEIGHT=0 make get_session + +############### +### TestNet ### +############### + +.PHONY: testnet_supplier_list +testnet_supplier_list: ## List all the staked supplier on TestNet + poktrolld q supplier list-supplier --node=$(TESTNET_RPC) + +.PHONY: testnet_gateway_list +testnet_gateway_list: ## List all the staked gateways on TestNet + poktrolld q gateway list-gateway --node=$(TESTNET_RPC) + +.PHONY: testnet_app_list +testnet_app_list: ## List all the staked applications on TestNet + poktrolld q application list-application --node=$(TESTNET_RPC) + +.PHONY: testnet_consensus_params +testnet_consensus_params: ## Output consensus parameters + poktrolld q consensus params --node=$(TESTNET_RPC) + +.PHONY: testnet_gov_params +testnet_gov_params: ## Output gov parameters + poktrolld q gov params --node=$(TESTNET_RPC) + +.PHONY: testnet_status +testnet_status: ## Output status of the RPC node (most likely a validator) + poktrolld status --node=$(TESTNET_RPC) | jq + +.PHONY: testnet_height +testnet_height: ## Height of the network from the RPC node point of view + poktrolld status --node=$(TESTNET_RPC) | jq ".sync_info.latest_block_height" + ################ ### Accounts ### ################ @@ -270,6 +833,161 @@ acc_initialize_pubkeys: ## Make sure the account keeper has public keys for all --home=$(POKTROLLD_HOME) \ --node $(POCKET_NODE);) +######################## +### Warning Messages ### +######################## + +.PHONY: warn_message_acc_initialize_pubkeys +warn_message_acc_initialize_pubkeys: ## Print a warning message about the need to run `make acc_initialize_pubkeys` + @echo "+----------------------------------------------------------------------------------+" + @echo "| |" + @echo "| IMPORTANT: Please run the following command once to initialize |" + @echo "| E2E tests after the network has started: |" + @echo "| |" + @echo "| make acc_initialize_pubkeys |" + @echo "| |" + @echo "+----------------------------------------------------------------------------------+" + +.PHONY: warn_message_local_stress_test +warn_message_local_stress_test: ## Print a warning message when kicking off a local E2E relay stress test + @echo "+-----------------------------------------------------------------------------------------------+" + @echo "| |" + @echo "| IMPORTANT: Please read the following before continuing with the stress test. |" + @echo "| |" + @echo "| 1. Review the # of suppliers & gateways in 'load-testing/localnet_loadtest_manifest.yaml' |" + @echo "| 2. Update 'localnet_config.yaml' to reflect what you found in (1) |" + @echo "| DEVELOPER_TIP: If you're operating off defaults, you'll likely need to update to 3 |" + @echo "| |" + @echo "| TODO_DOCUMENT(@okdas): Move this into proper documentation w/ clearer explanations |" + @echo "| |" + @echo "+-----------------------------------------------------------------------------------------------+" + +PHONY: warn_flaky_tests +warn_flaky_tests: ## Print a warning message that some unit tests may be flaky + @echo "+-----------------------------------------------------------------------------------------------+" + @echo "| |" + @echo "| IMPORTANT: READ ME IF YOUR TESTS FAIL!!! |" + @echo "| |" + @echo "| 1. Our unit / integration tests are far from perfect & some are flaky |" + @echo "| 2. If you ran 'make go_develop_and_test' and a failure occurred, try to run: |" + @echo "| 'make test_all' once or twice more |" + @echo "| 3. If the same error persists, isolate it with 'go test -v ./path/to/failing/module |" + @echo "| |" + @echo "+-----------------------------------------------------------------------------------------------+" + +############## +### Claims ### +############## + +# These encoded values were generated using the `encodeSessionHeader` helpers in `query_claim_test.go` as dummy values. +ENCODED_SESSION_HEADER = "eyJhcHBsaWNhdGlvbl9hZGRyZXNzIjoicG9rdDFleXJuNDUwa3JoZnpycmVyemd0djd2c3J4bDA5NDN0dXN4azRhayIsInNlcnZpY2UiOnsiaWQiOiJhbnZpbCIsIm5hbWUiOiIifSwic2Vzc2lvbl9zdGFydF9ibG9ja19oZWlnaHQiOiI1Iiwic2Vzc2lvbl9pZCI6InNlc3Npb25faWQxIiwic2Vzc2lvbl9lbmRfYmxvY2tfaGVpZ2h0IjoiOSJ9" +ENCODED_ROOT_HASH = "cm9vdF9oYXNo" +.PHONY: claim_create_dummy +claim_create_dummy: ## Create a dummy claim by supplier1 + poktrolld --home=$(POKTROLLD_HOME) tx supplier create-claim \ + $(ENCODED_SESSION_HEADER) \ + $(ENCODED_ROOT_HASH) \ + --from supplier1 --node $(POCKET_NODE) + +.PHONY: claims_list +claim_list: ## List all the claims + poktrolld --home=$(POKTROLLD_HOME) q supplier list-claims --node $(POCKET_NODE) + +.PHONY: claims_list_address +claim_list_address: ## List all the claims for a specific address (specified via ADDR variable) + poktrolld --home=$(POKTROLLD_HOME) q supplier list-claims --supplier-operator-address $(ADDR) --node $(POCKET_NODE) + +.PHONY: claims_list_address_supplier1 +claim_list_address_supplier1: ## List all the claims for supplier1 + SUPPLIER1=$$(make poktrolld_addr ACC_NAME=supplier1) && \ + ADDR=$$SUPPLIER1 make claim_list_address + +.PHONY: claim_list_height +claim_list_height: ## List all the claims ending at a specific height (specified via HEIGHT variable) + poktrolld --home=$(POKTROLLD_HOME) q supplier list-claims --session-end-height $(HEIGHT) --node $(POCKET_NODE) + +.PHONY: claim_list_height_5 +claim_list_height_5: ## List all the claims at height 5 + HEIGHT=5 make claim_list_height + +.PHONY: claim_list_session +claim_list_session: ## List all the claims ending at a specific session (specified via SESSION variable) + poktrolld --home=$(POKTROLLD_HOME) q supplier list-claims --session-id $(SESSION) --node $(POCKET_NODE) + +############## +### Params ### +############## + +# TODO_CONSIDERATION: additional factoring (e.g. POKTROLLD_FLAGS). +PARAM_FLAGS = --home=$(POKTROLLD_HOME) --keyring-backend test --from $(PNF_ADDRESS) --node $(POCKET_NODE) + +### Tokenomics Module Params ### +.PHONY: update_tokenomics_params_all +params_update_tokenomics_all: ## Update the tokenomics module params + poktrolld tx authz exec ./tools/scripts/params/tokenomics_all.json $(PARAM_FLAGS) + +.PHONY: params_update_tokenomics_compute_units_to_tokens_multiplier +params_update_tokenomics_compute_units_to_tokens_multiplier: ## Update the tokenomics module compute_units_to_tokens_multiplier param + poktrolld tx authz exec ./tools/scripts/params/tokenomics_compute_units_to_tokens_multiplier.json $(PARAM_FLAGS) + +### Proof Module Params ### +.PHONY: params_update_proof_all +params_update_proof_all: ## Update the proof module params + poktrolld tx authz exec ./tools/scripts/params/proof_all.json $(PARAM_FLAGS) + +.PHONY: params_update_proof_min_relay_difficulty_bits +params_update_proof_min_relay_difficulty_bits: ## Update the proof module min_relay_difficulty_bits param + poktrolld tx authz exec ./tools/scripts/params/proof_min_relay_difficulty_bits.json $(PARAM_FLAGS) + +.PHONY: params_update_proof_proof_request_probability +params_update_proof_proof_request_probability: ## Update the proof module proof_request_probability param + poktrolld tx authz exec ./tools/scripts/params/proof_proof_request_probability.json $(PARAM_FLAGS) + +.PHONY: params_update_proof_proof_requirement_threshold +params_update_proof_proof_requirement_threshold: ## Update the proof module proof_requirement_threshold param + poktrolld tx authz exec ./tools/scripts/params/proof_proof_requirement_threshold.json $(PARAM_FLAGS) + +.PHONY: params_update_proof_proof_missing_penalty +params_update_proof_proof_missing_penalty: ## Update the proof module proof_missing_penalty param + poktrolld tx authz exec ./tools/scripts/params/proof_proof_missing_penalty.json $(PARAM_FLAGS) + +### Shared Module Params ### +.PHONY: params_update_shared_all +params_update_shared_all: ## Update the session module params + poktrolld tx authz exec ./tools/scripts/params/shared_all.json $(PARAM_FLAGS) + +.PHONY: params_update_shared_num_blocks_per_session +params_update_shared_num_blocks_per_session: ## Update the shared module num_blocks_per_session param + poktrolld tx authz exec ./tools/scripts/params/shared_num_blocks_per_session.json $(PARAM_FLAGS) + +.PHONY: params_update_shared_grace_period_end_offset_blocks +params_update_shared_grace_period_end_offset_blocks: ## Update the shared module grace_period_end_offset_blocks param + poktrolld tx authz exec ./tools/scripts/params/shared_grace_period_end_offset_blocks.json $(PARAM_FLAGS) + +.PHONY: params_update_shared_claim_window_open_offset_blocks +params_update_shared_claim_window_open_offset_blocks: ## Update the shared module claim_window_open_offset_blocks param + poktrolld tx authz exec ./tools/scripts/params/shared_claim_window_open_offset_blocks.json $(PARAM_FLAGS) + +.PHONY: params_update_shared_claim_window_close_offset_blocks +params_update_shared_claim_window_close_offset_blocks: ## Update the shared module claim_window_close_offset_blocks param + poktrolld tx authz exec ./tools/scripts/params/shared_claim_window_close_offset_blocks.json $(PARAM_FLAGS) + +.PHONY: params_update_shared_proof_window_open_offset_blocks +params_update_shared_proof_window_open_offset_blocks: ## Update the shared module proof_window_open_offset_blocks param + poktrolld tx authz exec ./tools/scripts/params/shared_proof_window_open_offset_blocks.json $(PARAM_FLAGS) + +.PHONY: params_update_shared_proof_window_close_offset_blocks +params_update_shared_proof_window_close_offset_blocks: ## Update the shared module proof_window_close_offset_blocks param + poktrolld tx authz exec ./tools/scripts/params/shared_proof_window_close_offset_blocks.json $(PARAM_FLAGS) + +.PHONY: params_query_all +params_query_all: check_jq ## Query the params from all available modules + @for module in $(MODULES); do \ + echo "~~~ Querying $$module module params ~~~"; \ + poktrolld query $$module params --node $(POCKET_NODE) --output json | jq; \ + echo ""; \ + done + ###################### ### Ignite Helpers ### ###################### @@ -404,7 +1122,6 @@ act_reviewdog: check_act check_gh ## Run the reviewdog workflow locally like so: @echo "Detected architecture: $(CONTAINER_ARCH)" act -v -s GITHUB_TOKEN=$(GITHUB_TOKEN) -W .github/workflows/reviewdog.yml --container-architecture $(CONTAINER_ARCH) - ########################### ### Release Helpers ### ########################### diff --git a/Tiltfile b/Tiltfile index 7a9af482d..9a104a3d2 100644 --- a/Tiltfile +++ b/Tiltfile @@ -264,10 +264,8 @@ helm_resource( actor_number = 0 for x in range(localnet_config["relayminers"]["count"]): actor_number = actor_number + 1 - helm_resource( - "relayminer" + str(actor_number), - chart_prefix + "relayminer", - flags=[ + + flags = [ "--values=./localnet/kubernetes/values-common.yaml", "--values=./localnet/kubernetes/values-relayminer-common.yaml", "--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + ".yaml", @@ -276,6 +274,21 @@ for x in range(localnet_config["relayminers"]["count"]): "--set=logLevel=" + str(localnet_config["relayminers"]["logs"]["level"]), "--set=image.repository=poktrolld", ], + ] + + if localnet_config["rest"]["enabled"]: + flags.append("--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + "-rest" + ".yaml") + + if localnet_config["ollama"]["enabled"]: + flags.append("--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + "-ollama" + ".yaml") + + if localnet_config["rest"]["enabled"] and localnet_config["ollama"]["enabled"]: + flags.append("--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + "-all" + ".yaml") + + helm_resource( + "relayminer" + str(actor_number), + chart_prefix + "relayminer", + flags=flags, image_deps=["poktrolld"], image_keys=[("image.repository", "image.tag")], ) @@ -299,6 +312,7 @@ for x in range(localnet_config["relayminers"]["count"]): # Use with pprof like this: `go tool pprof -http=:3333 http://localhost:6070/debug/pprof/goroutine` str(6069 + actor_number) + ":6060", # Relayminer pprof port. relayminer1 - exposes 6070, relayminer2 exposes 6071, etc. + str(7000 + actor_number) + ":8081", # Relayminer ping port. relayminer1 - exposes 7001, relayminer2 exposes 7002, ect. ], ) diff --git a/localnet/kubernetes/values-relayminer-1-all.yaml b/localnet/kubernetes/values-relayminer-1-all.yaml new file mode 100644 index 000000000..4b5bb730e --- /dev/null +++ b/localnet/kubernetes/values-relayminer-1-all.yaml @@ -0,0 +1,20 @@ +config: + suppliers: + - service_id: anvil + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://anvil:8547/ + publicly_exposed_endpoints: + - relayminer1 + - service_id: rest + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://rest:10000/ + publicly_exposed_endpoints: + - relayminer1 + - service_id: ollama + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://ollama:11434/ + publicly_exposed_endpoints: + - relayminer1 diff --git a/localnet/kubernetes/values-relayminer-1-ollama.yaml b/localnet/kubernetes/values-relayminer-1-ollama.yaml new file mode 100644 index 000000000..eb90af154 --- /dev/null +++ b/localnet/kubernetes/values-relayminer-1-ollama.yaml @@ -0,0 +1,14 @@ +config: + suppliers: + - service_id: anvil + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://anvil:8547/ + publicly_exposed_endpoints: + - relayminer1 + - service_id: ollama + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://ollama:11434/ + publicly_exposed_endpoints: + - relayminer1 diff --git a/localnet/kubernetes/values-relayminer-1-rest.yaml b/localnet/kubernetes/values-relayminer-1-rest.yaml new file mode 100644 index 000000000..ca68d24ea --- /dev/null +++ b/localnet/kubernetes/values-relayminer-1-rest.yaml @@ -0,0 +1,14 @@ +config: + suppliers: + - service_id: anvil + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://anvil:8547/ + publicly_exposed_endpoints: + - relayminer1 + - service_id: rest + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://rest:10000/ + publicly_exposed_endpoints: + - relayminer1 diff --git a/localnet/kubernetes/values-relayminer-1.yaml b/localnet/kubernetes/values-relayminer-1.yaml index b17bd5765..35cc0240e 100644 --- a/localnet/kubernetes/values-relayminer-1.yaml +++ b/localnet/kubernetes/values-relayminer-1.yaml @@ -11,15 +11,3 @@ config: backend_url: http://anvil:8547/ publicly_exposed_endpoints: - relayminer1 - - service_id: ollama - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://ollama:11434/ - publicly_exposed_endpoints: - - relayminer1 - - service_id: rest - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://rest:10000/ - publicly_exposed_endpoints: - - relayminer1 diff --git a/localnet/kubernetes/values-relayminer-2-ollama.yaml b/localnet/kubernetes/values-relayminer-2-ollama.yaml new file mode 100644 index 000000000..21957cd08 --- /dev/null +++ b/localnet/kubernetes/values-relayminer-2-ollama.yaml @@ -0,0 +1,14 @@ +config: + suppliers: + - service_id: anvil + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://anvil:8547/ + publicly_exposed_endpoints: + - relayminer2 + - service_id: ollama + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://ollama:11434/ + publicly_exposed_endpoints: + - relayminer2 diff --git a/localnet/kubernetes/values-relayminer-2.yaml b/localnet/kubernetes/values-relayminer-2.yaml index de12138d4..2110bc000 100644 --- a/localnet/kubernetes/values-relayminer-2.yaml +++ b/localnet/kubernetes/values-relayminer-2.yaml @@ -11,9 +11,3 @@ config: backend_url: http://anvil:8547/ publicly_exposed_endpoints: - relayminer2 - - service_id: ollama - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://ollama:11434/ - publicly_exposed_endpoints: - - relayminer2 diff --git a/localnet/kubernetes/values-relayminer-3-ollama.yaml b/localnet/kubernetes/values-relayminer-3-ollama.yaml new file mode 100644 index 000000000..f585f0066 --- /dev/null +++ b/localnet/kubernetes/values-relayminer-3-ollama.yaml @@ -0,0 +1,14 @@ +config: + suppliers: + - service_id: anvil + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://anvil:8547/ + publicly_exposed_endpoints: + - relayminer3 + - service_id: ollama + listen_url: http://0.0.0.0:8545 + service_config: + backend_url: http://ollama:11434/ + publicly_exposed_endpoints: + - relayminer3 diff --git a/localnet/kubernetes/values-relayminer-3.yaml b/localnet/kubernetes/values-relayminer-3.yaml index 624aaa1bf..5a9cf0ec8 100644 --- a/localnet/kubernetes/values-relayminer-3.yaml +++ b/localnet/kubernetes/values-relayminer-3.yaml @@ -11,9 +11,3 @@ config: backend_url: http://anvil:8547/ publicly_exposed_endpoints: - relayminer3 - - service_id: ollama - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://ollama:11434/ - publicly_exposed_endpoints: - - relayminer3 diff --git a/localnet/kubernetes/values-relayminer-common.yaml b/localnet/kubernetes/values-relayminer-common.yaml index 207c636b2..f4fbe4b5b 100644 --- a/localnet/kubernetes/values-relayminer-common.yaml +++ b/localnet/kubernetes/values-relayminer-common.yaml @@ -11,3 +11,6 @@ config: pprof: enabled: true addr: localhost:6060 + ping: + enabled: true + addr: localhost:8081 From d3710d88c5499e61444873b857fd82003777851c Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 10 Nov 2024 23:12:28 +0100 Subject: [PATCH 10/55] use errors.Join instead of appending errors slice --- pkg/relayer/interface.go | 2 +- pkg/relayer/proxy/proxy.go | 15 ++++++++------- pkg/relayer/proxy/proxy_test.go | 6 ++---- pkg/relayer/relayminer.go | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/pkg/relayer/interface.go b/pkg/relayer/interface.go index 310a8692d..3b8656db6 100644 --- a/pkg/relayer/interface.go +++ b/pkg/relayer/interface.go @@ -75,7 +75,7 @@ type RelayerProxy interface { SignRelayResponse(relayResponse *servicetypes.RelayResponse, supplierOperatorAddr string) error // PingAll tests the connectivity between all the managed relay servers and their respective backend URLs. - PingAll(ctx context.Context) []error + PingAll(ctx context.Context) error } type RelayerProxyOption func(RelayerProxy) diff --git a/pkg/relayer/proxy/proxy.go b/pkg/relayer/proxy/proxy.go index dde13e17d..1dac8570a 100644 --- a/pkg/relayer/proxy/proxy.go +++ b/pkg/relayer/proxy/proxy.go @@ -2,6 +2,7 @@ package proxy import ( "context" + "errors" "cosmossdk.io/depinject" "github.com/cosmos/cosmos-sdk/crypto/keyring" @@ -214,19 +215,19 @@ func (rp *relayerProxy) validateConfig() error { } // PingAll tests the connectivity between all the managed relay servers and their respective backend URLs. -func (rp *relayerProxy) PingAll(ctx context.Context) []error { - var errs []error +func (rp *relayerProxy) PingAll(ctx context.Context) error { + var err error for _, srv := range rp.servers { if err := srv.Ping(ctx); err != nil { - rp.logger.Error().Err(err). - Msg("an unexpected error occured while pinging backend URL") - errs = append(errs, err) + err = errors.Join(err, err) } } - if len(errs) > 0 { - return errs + if err != nil { + rp.logger.Error().Err(err). + Msg("an unexpected error occured while pinging backend URL") + return err } return nil diff --git a/pkg/relayer/proxy/proxy_test.go b/pkg/relayer/proxy/proxy_test.go index 330656b33..7594140ee 100644 --- a/pkg/relayer/proxy/proxy_test.go +++ b/pkg/relayer/proxy/proxy_test.go @@ -151,10 +151,8 @@ func TestRelayerProxy_StartAndStop(t *testing.T) { // Block so relayerProxy has sufficient time to start time.Sleep(100 * time.Millisecond) - errs := rp.PingAll(ctx) - for _, err := range errs { - require.NoError(t, err) - } + err = rp.PingAll(ctx) + require.NoError(t, err) // Test that RelayerProxy is handling requests (ignoring the actual response content) res, err := http.DefaultClient.Get(fmt.Sprintf("http://%s/", servicesConfigMap[defaultRelayMinerServer].ListenAddress)) diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index 249d4f330..c7a19ea94 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -146,7 +146,7 @@ func (rel *relayMiner) ServePing(ctx context.Context, ln net.Listener) error { if err := http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { rel.logger.Debug().Msg("pinging relay servers...") - if errs := rel.relayerProxy.PingAll(ctx); errs != nil { + if err := rel.relayerProxy.PingAll(ctx); err != nil { w.WriteHeader(http.StatusInternalServerError) return } From 88300103251b9d0ef3ce411b1d4788419b59a4e3 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 10 Nov 2024 23:14:49 +0100 Subject: [PATCH 11/55] change c to httpClient in sychronous in relay server --- pkg/relayer/proxy/synchronous.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/relayer/proxy/synchronous.go b/pkg/relayer/proxy/synchronous.go index a1ef040a9..9ee1f2fb5 100644 --- a/pkg/relayer/proxy/synchronous.go +++ b/pkg/relayer/proxy/synchronous.go @@ -101,9 +101,9 @@ func (sync *synchronousRPCServer) Stop(ctx context.Context) error { // Ping tries to dial the suppliers backend URLs to test the connection. func (sync *synchronousRPCServer) Ping(ctx context.Context) error { for _, supplierCfg := range sync.serverConfig.SupplierConfigsMap { - c := &http.Client{Timeout: 2 * time.Second} + httpClient := &http.Client{Timeout: 2 * time.Second} - resp, err := c.Head(supplierCfg.ServiceConfig.BackendUrl.String()) + resp, err := httpClient.Head(supplierCfg.ServiceConfig.BackendUrl.String()) if err != nil { return err } From 86976f1301acd35728d6e4d0ba84aac923e1d8ad Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 10 Nov 2024 23:55:44 +0100 Subject: [PATCH 12/55] add relayer miner suppplier not reachable error --- pkg/relayer/proxy/errors.go | 1 + pkg/relayer/proxy/synchronous.go | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/relayer/proxy/errors.go b/pkg/relayer/proxy/errors.go index ff2fc285f..f52544f21 100644 --- a/pkg/relayer/proxy/errors.go +++ b/pkg/relayer/proxy/errors.go @@ -20,4 +20,5 @@ var ( ErrRelayerProxyUnknownSession = sdkerrors.Register(codespace, 12, "relayer proxy encountered unknown session") ErrRelayerProxyRateLimited = sdkerrors.Register(codespace, 13, "offchain rate limit hit by relayer proxy") ErrRelayerProxyUnclaimRelayPrice = sdkerrors.Register(codespace, 14, "failed to unclaim relay price") + ErrRelayerProxySupplierNotReachable = sdkerrors.Register(codespace, 12, "supplier(s) not reachable") ) diff --git a/pkg/relayer/proxy/synchronous.go b/pkg/relayer/proxy/synchronous.go index 9ee1f2fb5..d3f2ee7d6 100644 --- a/pkg/relayer/proxy/synchronous.go +++ b/pkg/relayer/proxy/synchronous.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "crypto/tls" - "errors" "fmt" "io" "net/http" @@ -110,7 +109,7 @@ func (sync *synchronousRPCServer) Ping(ctx context.Context) error { _ = resp.Body.Close() if resp.StatusCode >= http.StatusInternalServerError { - return errors.New("ping failed") + return ErrRelayerProxySupplierNotReachable } } From 493884eef38d2a6385e5cd09cf513ad42633e0db Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 11 Nov 2024 00:12:56 +0100 Subject: [PATCH 13/55] add newpinghandlerfn function --- pkg/relayer/cmd/cmd.go | 4 +--- pkg/relayer/relayminer.go | 26 +++++++++++++++----------- pkg/relayer/relayminer_test.go | 3 +-- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/pkg/relayer/cmd/cmd.go b/pkg/relayer/cmd/cmd.go index 5278a5e69..749f06627 100644 --- a/pkg/relayer/cmd/cmd.go +++ b/pkg/relayer/cmd/cmd.go @@ -146,9 +146,7 @@ func runRelayer(cmd *cobra.Command, _ []string) error { return fmt.Errorf("failed to listen ping server: %w", err) } - if err := relayMiner.ServePing(ctx, ln); err != nil { - return fmt.Errorf("failed to start ping server: %w", err) - } + relayMiner.ServePing(ctx, ln) } // Start the relay miner diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index c7a19ea94..ccb788837 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -138,24 +138,28 @@ func (rel *relayMiner) ServePprof(ctx context.Context, addr string) error { // ServePing exposes ping HTTP server to check the reachability between the // relay miner and its dependencies (Ex: relay server and their respective // backend URLs). -func (rel *relayMiner) ServePing(ctx context.Context, ln net.Listener) error { +func (rel *relayMiner) ServePing(ctx context.Context, ln net.Listener) { // Start a long-lived goroutine that starts an HTTP server responding to // ping requests. A single ping request on the relay server broadcasts a // ping to all backing services/data nodes. go func() { - if err := http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - rel.logger.Debug().Msg("pinging relay servers...") + if err := http.Serve(ln, rel.newPinghandlerFn(ctx, ln)); err != nil { + rel.logger.Error().Err(err).Msg("unable to serve ping server") + } + }() + + return +} - if err := rel.relayerProxy.PingAll(ctx); err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } +func (rel *relayMiner) newPinghandlerFn(ctx context.Context, ln net.Listener) http.HandlerFunc { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + rel.logger.Debug().Msg("pinging relay servers...") - w.WriteHeader(http.StatusOK) - })); err != nil { + if err := rel.relayerProxy.PingAll(ctx); err != nil { + w.WriteHeader(http.StatusInternalServerError) return } - }() - return nil + w.WriteHeader(http.StatusOK) + }) } diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index 930d4e11b..9fd7467ee 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -106,8 +106,7 @@ func TestRelayMiner_Ping(t *testing.T) { require.NoError(t, err) defer os.Remove(filename) - err = relayminer.ServePing(ctx, ln) - require.NoError(t, err) + relayminer.ServePing(ctx, ln) time.Sleep(time.Millisecond) From 1bf241edee84d997bf3ae9de7f504174ca76f873 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 11 Nov 2024 00:15:48 +0100 Subject: [PATCH 14/55] add comment relayminer test --- pkg/relayer/relayminer_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index 9fd7467ee..bdba36d33 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -62,9 +62,11 @@ func TestRelayMiner_StartAndStop(t *testing.T) { } func TestRelayMiner_Ping(t *testing.T) { + // servedRelaysObs is NEVER published to. It exists to satisfy test mocks. srObs, _ := channel.NewObservable[*servicetypes.Relay]() servedRelaysObs := relayer.RelaysObservable(srObs) + // minedRelaysObs is NEVER published to. It exists to satisfy test mocks. mrObs, _ := channel.NewObservable[*relayer.MinedRelay]() minedRelaysObs := relayer.MinedRelaysObservable(mrObs) From c23523277762c84781f53240261880ba471c6138 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 11 Nov 2024 00:30:16 +0100 Subject: [PATCH 15/55] simplified newmockonetimerelayerproxywithping function --- testutil/testrelayer/proxy.go | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/testutil/testrelayer/proxy.go b/testutil/testrelayer/proxy.go index 719bd2204..86168984d 100644 --- a/testutil/testrelayer/proxy.go +++ b/testutil/testrelayer/proxy.go @@ -46,20 +46,7 @@ func NewMockOneTimeRelayerProxyWithPing( t *testing.T, returnedRelaysObs relayer.RelaysObservable, ) *mockrelayer.MockRelayerProxy { - t.Helper() - - ctrl := gomock.NewController(t) - relayerProxyMock := mockrelayer.NewMockRelayerProxy(ctrl) - relayerProxyMock.EXPECT(). - Start(gomock.Eq(ctx)). - Times(1) - relayerProxyMock.EXPECT(). - Stop(gomock.Eq(ctx)). - Times(1) - relayerProxyMock.EXPECT(). - ServedRelays(). - Return(returnedRelaysObs). - Times(1) + relayerProxyMock := NewMockOneTimeRelayerProxy(ctx, t, returnedRelaysObs) relayerProxyMock.EXPECT(). PingAll(gomock.Eq(ctx)). Times(1) From 587cf443dc7ad3643b0e630011547e70243cf3a5 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 11 Nov 2024 00:37:51 +0100 Subject: [PATCH 16/55] revert Makefile and add local helpers --- Makefile | 782 +++---------------------------------------------------- 1 file changed, 43 insertions(+), 739 deletions(-) diff --git a/Makefile b/Makefile index 66caf8581..71d0b2a44 100644 --- a/Makefile +++ b/Makefile @@ -80,10 +80,39 @@ endif .PHONY: install_ci_deps install_ci_deps: ## Installs `mockgen` and other go tools go install "github.com/golang/mock/mockgen@v1.6.0" && mockgen --version - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.1 && golangci-lint --version + go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.60.3 && golangci-lint --version go install golang.org/x/tools/cmd/goimports@latest go install github.com/mikefarah/yq/v4@latest +.PHONY: install_cosmovisor +install_cosmovisor: ## Installs `cosmovisor` + go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@v1.6.0 && cosmovisor version --cosmovisor-only + +.PHONY: cosmovisor_cross_compile +cosmovisor_cross_compile: # Installs multiple cosmovisor binaries for different platforms (used by Dockerfile.release) + @COSMOVISOR_VERSION="v1.6.0"; \ + PLATFORMS="linux/amd64 linux/arm64"; \ + mkdir -p ./tmp; \ + echo "Fetching Cosmovisor source..."; \ + temp_dir=$$(mktemp -d); \ + cd $$temp_dir; \ + go mod init temp; \ + go get cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@$$COSMOVISOR_VERSION; \ + for platform in $$PLATFORMS; do \ + OS=$${platform%/*}; \ + ARCH=$${platform#*/}; \ + echo "Compiling for $$OS/$$ARCH..."; \ + GOOS=$$OS GOARCH=$$ARCH go build -o $(CURDIR)/tmp/cosmovisor-$$OS-$$ARCH cosmossdk.io/tools/cosmovisor/cmd/cosmovisor; \ + done; \ + cd $(CURDIR); \ + rm -rf $$temp_dir; \ + echo "Compilation complete. Binaries are in ./tmp/"; \ + ls -l ./tmp/cosmovisor-* + +.PHONY: cosmovisor_clean +cosmovisor_clean: + rm -f ./tmp/cosmovisor-* + ######################## ### Makefile Helpers ### ######################## @@ -102,167 +131,6 @@ list: ## List all make targets help: ## Prints all the targets in all the Makefiles @grep -h -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-60s\033[0m %s\n", $$1, $$2}' -############## -### Checks ### -############## - -# TODO_DOCUMENT: All of the `check_` helpers can be installed differently depending -# on the user's OS and environment. -# NB: For mac users, you may need to install with the proper linkers: https://github.com/golang/go/issues/65940 - -.PHONY: check_go_version -# Internal helper target - check go version -check_go_version: - @# Extract the version number from the `go version` command. - @GO_VERSION=$$(go version | cut -d " " -f 3 | cut -c 3-) && \ - MAJOR_VERSION=$$(echo $$GO_VERSION | cut -d "." -f 1) && \ - MINOR_VERSION=$$(echo $$GO_VERSION | cut -d "." -f 2) && \ - \ - if [ "$$MAJOR_VERSION" -ne 1 ] || [ "$$MINOR_VERSION" -le 20 ] ; then \ - echo "Invalid Go version. Expected 1.21.x or newer but found $$GO_VERSION"; \ - exit 1; \ - fi - -.PHONY: check_ignite_version -# Internal helper target - check ignite version -check_ignite_version: - @version=$$(ignite version 2>/dev/null | grep 'Ignite CLI version:' | awk '{print $$4}') ; \ - if [ "$$(printf "v28\n$$version" | sort -V | head -n1)" != "v28" ]; then \ - echo "Error: Version $$version is less than v28. Exiting with error." ; \ - exit 1 ; \ - fi - -.PHONY: check_mockgen -# Internal helper target- Check if mockgen is installed -check_mockgen: - { \ - if ( ! ( command -v mockgen >/dev/null )); then \ - echo "Seems like you don't have `mockgen` installed. Please visit https://github.com/golang/mock#installation and follow the instructions to install `mockgen` before continuing"; \ - exit 1; \ - fi; \ - } - - -.PHONY: check_act -# Internal helper target - check if `act` is installed -check_act: - { \ - if ( ! ( command -v act >/dev/null )); then \ - echo "Seems like you don't have `act` installed. Please visit https://github.com/nektos/act before continuing"; \ - exit 1; \ - fi; \ - } - -.PHONY: check_gh -# Internal helper target - check if `gh` is installed -check_gh: - { \ - if ( ! ( command -v gh >/dev/null )); then \ - echo "Seems like you don't have `gh` installed. Please visit https://cli.github.com/ before continuing"; \ - exit 1; \ - fi; \ - } - -.PHONY: check_docker -# Internal helper target - check if docker is installed -check_docker: - { \ - if ( ! ( command -v docker >/dev/null && (docker compose version >/dev/null || command -v docker-compose >/dev/null) )); then \ - echo "Seems like you don't have Docker or docker-compose installed. Make sure you review build/localnet/README.md and docs/development/README.md before continuing"; \ - exit 1; \ - fi; \ - } -.PHONY: check_kind -# Internal helper target - check if kind is installed -check_kind: - @if ! command -v kind >/dev/null 2>&1; then \ - echo "kind is not installed. Make sure you review build/localnet/README.md and docs/development/README.md before continuing"; \ - exit 1; \ - fi - -.PHONY: check_docker_ps - ## Internal helper target - checks if Docker is running -check_docker_ps: check_docker - @echo "Checking if Docker is running..." - @docker ps > /dev/null 2>&1 || (echo "Docker is not running. Please start Docker and try again."; exit 1) - -.PHONY: check_kind_context -## Internal helper target - checks if the kind-kind context exists and is set -check_kind_context: check_kind - @if ! kubectl config get-contexts | grep -q 'kind-kind'; then \ - echo "kind-kind context does not exist. Please create it or switch to it."; \ - exit 1; \ - fi - @if ! kubectl config current-context | grep -q 'kind-kind'; then \ - echo "kind-kind context is not currently set. Use 'kubectl config use-context kind-kind' to set it."; \ - exit 1; \ - fi - - -.PHONY: check_godoc -# Internal helper target - check if godoc is installed -check_godoc: - { \ - if ( ! ( command -v godoc >/dev/null )); then \ - echo "Seems like you don't have godoc installed. Make sure you install it via 'go install golang.org/x/tools/cmd/godoc@latest' before continuing"; \ - exit 1; \ - fi; \ - } - -.PHONY: check_npm -# Internal helper target - check if npm is installed -check_npm: - { \ - if ( ! ( command -v npm >/dev/null )); then \ - echo "Seems like you don't have npm installed. Make sure you install it before continuing"; \ - exit 1; \ - fi; \ - } - -.PHONY: check_jq -# Internal helper target - check if jq is installed -check_jq: - { \ - if ( ! ( command -v jq >/dev/null )); then \ - echo "Seems like you don't have jq installed. Make sure you install it before continuing"; \ - exit 1; \ - fi; \ - } - -.PHONY: check_yq -# Internal helper target - check if `yq` is installed -check_yq: - { \ - if ( ! ( command -v yq >/dev/null )); then \ - echo "Seems like you don't have `yq` installed. Make sure you install it before continuing"; \ - exit 1; \ - fi; \ - } - -.PHONY: check_node -# Internal helper target - check if node is installed -check_node: - { \ - if ( ! ( command -v node >/dev/null )); then \ - echo "Seems like you don't have node installed. Make sure you install it before continuing"; \ - exit 1; \ - fi; \ - } - -.PHONY: check_proto_unstable_marshalers -check_proto_unstable_marshalers: ## Check that all protobuf files have the `stable_marshalers_all` option set to true. - go run ./tools/scripts/protocheck/cmd unstable - -.PHONY: fix_proto_unstable_marshalers -fix_proto_unstable_marshalers: ## Ensure the `stable_marshaler_all` option is present on all protobuf files. - go run ./tools/scripts/protocheck/cmd unstable --fix - ${MAKE} proto_regen - - -.PHONY: warn_destructive -warn_destructive: ## Print WARNING to the user - @echo "This is a destructive action that will affect docker resources outside the scope of this repo!" - ####################### ### Proto Helpers #### ####################### @@ -302,85 +170,38 @@ proto_clean_pulsar: ## TODO_TECHDEBT(@bryanchriswhite): Add a proper explanation .PHONY: proto_regen proto_regen: proto_clean proto_ignite_gen proto_fix_self_import ## Regenerate protobuf artifacts -####################### -### Docker Helpers ### -####################### - -.PHONY: docker_wipe -docker_wipe: check_docker warn_destructive prompt_user ## [WARNING] Remove all the docker containers, images and volumes. - docker ps -a -q | xargs -r -I {} docker stop {} - docker ps -a -q | xargs -r -I {} docker rm {} - docker images -q | xargs -r -I {} docker rmi {} - docker volume ls -q | xargs -r -I {} docker volume rm {} - ######################## ### Localnet Helpers ### ######################## -.PHONY: localnet_up -localnet_up: check_docker_ps check_kind_context proto_regen localnet_regenesis ## Starts up a clean localnet - tilt up - -.PHONY: localnet_up_quick -localnet_up_quick: check_docker_ps check_kind_context ## Starts up a localnet without regenerating fixtures - tilt up - -.PHONY: localnet_down -localnet_down: ## Delete resources created by localnet - tilt down - -.PHONY: localnet_regenesis -localnet_regenesis: check_yq warn_message_acc_initialize_pubkeys ## Regenerate the localnet genesis file -# NOTE: intentionally not using --home flag to avoid overwriting the test keyring - @echo "Initializing chain..." - @set -e - @ignite chain init --skip-proto - AUTH_CONTENT=$$(cat ./tools/scripts/authz/dao_genesis_authorizations.json | jq -r tostring); \ - $(SED) -i -E 's!^(\s*)"authorization": (\[\]|null)!\1"authorization": '$$AUTH_CONTENT'!' ${HOME}/.poktroll/config/genesis.json; - - @cp -r ${HOME}/.poktroll/keyring-test $(POKTROLLD_HOME) - @cp -r ${HOME}/.poktroll/config $(POKTROLLD_HOME)/ - -.PHONE: localnet_relayminer1_ping +.PHONY: localnet_relayminer1_ping localnet_relayminer1_ping: @echo "Pinging relayminer 1..." @curl -X GET localhost:7001 || (echo "Failed to ping relayminer1. Make sure your localnet environment or your relayminer pod is up and running"; exit 1) @echo "OK" -.PHONE: localnet_relayminer2_ping +.PHONY: localnet_relayminer2_ping localnet_relayminer2_ping: @echo "Pinging relayminer 2..." @curl -X GET localhost:7002 || (echo "Failed to ping relayminer2. Make sure your localnet environment or your relayminer pod is up and running"; exit 1) @echo "OK" -.PHONE: localnet_relayminer3_ping +.PHONY: localnet_relayminer3_ping localnet_relayminer3_ping: @echo "Pinging relayminer 3..." @curl -X GET localhost:7003 || (echo "Failed to ping relayminer3. Make sure your localnet environment or your relayminer pod is up and running"; exit 1) @echo "OK" -.PHONY: send_relay_sovereign_app_JSONRPC -send_relay_sovereign_app_JSONRPC: # Send a JSONRPC relay through the AppGateServer as a sovereign application - curl -X POST -H "Content-Type: application/json" \ - --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ - $(APPGATE_SERVER)/anvil - -.PHONY: send_relay_delegating_app_JSONRPC -send_relay_delegating_app_JSONRPC: # Send a relay through the gateway as an application that's delegating to this gateway - @appAddr=$$(poktrolld keys show app1 -a) && \ - curl -X POST -H "Content-Type: application/json" \ - --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ - $(GATEWAY_URL)/anvil?applicationAddr=$$appAddr - -.PHONY: send_relay_sovereign_app_REST -send_relay_sovereign_app_REST: # Send a REST relay through the AppGateServer as a sovereign application - curl -X POST -H "Content-Type: application/json" \ - --data '{"model": "qwen:0.5b", "stream": false, "messages": [{"role": "user", "content":"count from 1 to 10"}]}' \ - $(APPGATE_SERVER)/ollama/api/chat - -.PHONY: cosmovisor_start_node -cosmovisor_start_node: # Starts the node using cosmovisor that waits for an upgrade plan - bash tools/scripts/upgrades/cosmovisor-start-node.sh +####################### +### Docker Helpers ### +####################### + +.PHONY: docker_wipe +docker_wipe: check_docker warn_destructive prompt_user ## [WARNING] Remove all the docker containers, images and volumes. + docker ps -a -q | xargs -r -I {} docker stop {} + docker ps -a -q | xargs -r -I {} docker rm {} + docker images -q | xargs -r -I {} docker rmi {} + docker volume ls -q | xargs -r -I {} docker volume rm {} ############### ### Linting ### @@ -393,96 +214,6 @@ go_lint: ## Run all go linters go_imports: check_go_version ## Run goimports on all go files go run ./tools/scripts/goimports -############# -### Tests ### -############# - -.PHONY: test_e2e_env -test_e2e_env: warn_message_acc_initialize_pubkeys ## Setup the default env vars for E2E tests - export POCKET_NODE=$(POCKET_NODE) && \ - export APPGATE_SERVER=$(APPGATE_SERVER) && \ - export POKTROLLD_HOME=../../$(POKTROLLD_HOME) - -.PHONY: test_e2e -test_e2e: test_e2e_env ## Run all E2E tests - go test -count=1 -v ./e2e/tests/... -tags=e2e,test - -.PHONY: test_e2e_relay -test_e2e_relay: test_e2e_env ## Run only the E2E suite that exercises the relay life-cycle - go test -v ./e2e/tests/... -tags=e2e,test --features-path=relay.feature - -.PHONY: test_e2e_app -test_e2e_app: test_e2e_env ## Run only the E2E suite that exercises the application life-cycle - go test -v ./e2e/tests/... -tags=e2e,test --features-path=stake_app.feature - -.PHONY: test_e2e_supplier -test_e2e_supplier: test_e2e_env ## Run only the E2E suite that exercises the supplier life-cycle - go test -v ./e2e/tests/... -tags=e2e,test --features-path=stake_supplier.feature - -.PHONY: test_e2e_gateway -test_e2e_gateway: test_e2e_env ## Run only the E2E suite that exercises the gateway life-cycle - go test -v ./e2e/tests/... -tags=e2e,test --features-path=stake_gateway.feature - -.PHONY: test_e2e_session -test_e2e_session: test_e2e_env ## Run only the E2E suite that exercises the session (i.e. claim/proof) life-cycle - go test -v ./e2e/tests/... -tags=e2e,test --features-path=session.feature - -.PHONY: test_e2e_tokenomics -test_e2e_tokenomics: test_e2e_env ## Run only the E2E suite that exercises the session & tokenomics settlement - go test -v ./e2e/tests/... -tags=e2e,test --features-path=0_settlement.feature - -.PHONY: test_e2e_params -test_e2e_params: test_e2e_env ## Run only the E2E suite that exercises parameter updates for all modules - go test -v ./e2e/tests/... -tags=e2e,test --features-path=update_params.feature - -.PHONY: test_load_relays_stress_custom -test_load_relays_stress_custom: ## Run the stress test for E2E relays using custom manifest. "loadtest_manifest_example.yaml" manifest is used by default. Set `LOAD_TEST_CUSTOM_MANIFEST` environment variable to use the different manifest. - go test -v -count=1 ./load-testing/tests/... \ - -tags=load,test -run LoadRelays --log-level=debug --timeout=30m \ - --manifest ./load-testing/$(LOAD_TEST_CUSTOM_MANIFEST) - -.PHONY: test_load_relays_stress_localnet -test_load_relays_stress_localnet: test_e2e_env warn_message_local_stress_test ## Run the stress test for E2E relays on LocalNet. - go test -v -count=1 ./load-testing/tests/... \ - -tags=load,test -run LoadRelays --log-level=debug --timeout=30m \ - --manifest ./load-testing/loadtest_manifest_localnet.yaml - -.PHONY: test_load_relays_stress_localnet_single_supplier -test_load_relays_stress_localnet_single_supplier: test_e2e_env warn_message_local_stress_test ## Run the stress test for E2E relays on LocalNet using exclusively one supplier. - go test -v -count=1 ./load-testing/tests/... \ - -tags=load,test -run TestLoadRelaysSingleSupplier --log-level=debug --timeout=30m \ - --manifest ./load-testing/loadtest_manifest_localnet_single_supplier.yaml - -.PHONY: test_verbose -test_verbose: check_go_version ## Run all go tests verbosely - go test -count=1 -v -race -tags test ./... - -# NB: buildmode=pie is necessary to avoid linker errors on macOS. -# It is not compatible with `-race`, which is why it's omitted here. -# See ref for more details: https://github.com/golang/go/issues/54482#issuecomment-1251124908 -.PHONY: test_all -test_all: warn_flaky_tests check_go_version ## Run all go tests showing detailed output only on failures - go test -count=1 -buildmode=pie -tags test ./... - -.PHONY: test_all_with_integration -test_all_with_integration: check_go_version ## Run all go tests, including those with the integration - go test -count=1 -v -race -tags test,integration ./... - -# We are explicitly using an env variable rather than a build tag to keep flaky -# tests in line with non flaky tests and use it as a way to easily turn them -# on and off without maintaining extra files. -.PHONY: test_all_with_integration_and_flaky -test_all_with_integration_and_flaky: check_go_version ## Run all go tests, including those with the integration and flaky tests - INCLUDE_FLAKY_TESTS=true go test -count=1 -v -race -tags test,integration ./... - -.PHONY: test_integration -test_integration: check_go_version ## Run only the in-memory integration "unit" tests - go test -count=1 -v -race -tags test,integration ./tests/integration/... - -.PHONY: itest -itest: check_go_version ## Run tests iteratively (see usage for more) - ./tools/scripts/itest.sh $(filter-out $@,$(MAKECMDGOALS)) - .PHONY: go_mockgen go_mockgen: ## Use `mockgen` to generate mocks used for testing purposes of all the modules. find . -name "*_mock.go" | xargs --no-run-if-empty rm @@ -509,278 +240,6 @@ go_develop: check_ignite_version proto_regen go_mockgen ## Generate protos and m .PHONY: go_develop_and_test go_develop_and_test: go_develop test_all ## Generate protos, mocks and run all tests -############# -### TODOS ### -############# - -# How do I use TODOs? -# 1. : ; -# e.g. TODO_HACK: This is a hack, we need to fix it later -# 2. If there's a specific issue, or specific person, add that in paranthesiss -# e.g. TODO(@Olshansk): Automatically link to the Github user https://github.com/olshansk -# e.g. TODO_INVESTIGATE(#420): Automatically link this to github issue https://github.com/pokt-network/poktroll/issues/420 -# e.g. TODO_DISCUSS(@Olshansk, #420): Specific individual should tend to the action item in the specific ticket -# e.g. TODO_CLEANUP(core): This is not tied to an issue, or a person, but should only be done by the core team. -# e.g. TODO_CLEANUP: This is not tied to an issue, or a person, and can be done by the core team or external contributors. -# 3. Feel free to add additional keywords to the list above. - -# Inspired by @goldinguy_ in this post: https://goldin.io/blog/stop-using-todo ### -# TODO - General Purpose catch-all. -# TODO_COMMUNITY - A TODO that may be a candidate for outsourcing to the community. -# TODO_DECIDE - A TODO indicating we need to make a decision and document it using an ADR in the future; https://github.com/pokt-network/pocket-network-protocol/tree/main/ADRs -# TODO_TECHDEBT - Not a great implementation, but we need to fix it later. -# TODO_BLOCKER - BEFORE MAINNET. Similar to TECHDEBT, but of higher priority, urgency & risk prior to the next release -# TODO_QOL - AFTER MAINNET. Similar to TECHDEBT, but of lower priority. Doesn't deserve a GitHub Issue but will improve everyone's life. -# TODO_IMPROVE - A nice to have, but not a priority. It's okay if we never get to this. -# TODO_OPTIMIZE - An opportunity for performance improvement if/when it's necessary -# TODO_DISCUSS - Probably requires a lengthy offline discussion to understand next steps. -# TODO_INCOMPLETE - A change which was out of scope of a specific PR but needed to be documented. -# TODO_INVESTIGATE - TBD what was going on, but needed to continue moving and not get distracted. -# TODO_CLEANUP - Like TECHDEBT, but not as bad. It's okay if we never get to this. -# TODO_HACK - Like TECHDEBT, but much worse. This needs to be prioritized -# TODO_REFACTOR - Similar to TECHDEBT, but will require a substantial rewrite and change across the codebase -# TODO_CONSIDERATION - A comment that involves extra work but was thoughts / considered as part of some implementation -# TODO_CONSOLIDATE - We likely have similar implementations/types of the same thing, and we should consolidate them. -# TODO_ADDTEST / TODO_TEST - Add more tests for a specific code section -# TODO_FLAKY - Signals that the test is flaky and we are aware of it. Provide an explanation if you know why. -# TODO_DEPRECATE - Code that should be removed in the future -# TODO_RESEARCH - A non-trivial action item that requires deep research and investigation being next steps can be taken -# TODO_DOCUMENT - A comment that involves the creation of a README or other documentation -# TODO_BUG - There is a known existing bug in this code -# TODO_NB - An important note to reference later -# TODO_DISCUSS_IN_THIS_COMMIT - SHOULD NEVER BE COMMITTED TO MASTER. It is a way for the reviewer of a PR to start / reply to a discussion. -# TODO_IN_THIS_COMMIT - SHOULD NEVER BE COMMITTED TO MASTER. It is a way to start the review process while non-critical changes are still in progress - - -# Define shared variable for the exclude parameters -EXCLUDE_GREP = --exclude-dir={.git,vendor,./docusaurus,.vscode,.idea} --exclude={Makefile,reviewdog.yml,*.pb.go,*.pulsar.go} - -.PHONY: todo_list -todo_list: ## List all the TODOs in the project (excludes vendor and prototype directories) - grep -r $(EXCLUDE_GREP) TODO . | grep -v 'TODO()' - -.PHONY: todo_count -todo_count: ## Print a count of all the TODOs in the project - grep -r $(EXCLUDE_GREP) TODO . | grep -v 'TODO()' | wc -l - -.PHONY: todo_this_commit -todo_this_commit: ## List all the TODOs needed to be done in this commit - grep -r $(EXCLUDE_GREP) TODO_IN_THIS .| grep -v 'TODO()' - - -#################### -### Gateways ### -#################### - -.PHONY: gateway_list -gateway_list: ## List all the staked gateways - poktrolld --home=$(POKTROLLD_HOME) q gateway list-gateway --node $(POCKET_NODE) - -.PHONY: gateway_stake -gateway_stake: ## Stake tokens for the gateway specified (must specify the gateway env var) - poktrolld --home=$(POKTROLLD_HOME) tx gateway stake-gateway -y --config $(POKTROLLD_HOME)/config/$(STAKE) --keyring-backend test --from $(GATEWAY) --node $(POCKET_NODE) - -.PHONY: gateway1_stake -gateway1_stake: ## Stake gateway1 - GATEWAY=gateway1 STAKE=gateway1_stake_config.yaml make gateway_stake - -.PHONY: gateway2_stake -gateway2_stake: ## Stake gateway2 - GATEWAY=gateway2 STAKE=gateway2_stake_config.yaml make gateway_stake - -.PHONY: gateway3_stake -gateway3_stake: ## Stake gateway3 - GATEWAY=gateway3 STAKE=gateway3_stake_config.yaml make gateway_stake - -.PHONY: gateway_unstake -gateway_unstake: ## Unstake an gateway (must specify the GATEWAY env var) - poktrolld --home=$(POKTROLLD_HOME) tx gateway unstake-gateway -y --keyring-backend test --from $(GATEWAY) --node $(POCKET_NODE) - -.PHONY: gateway1_unstake -gateway1_unstake: ## Unstake gateway1 - GATEWAY=gateway1 make gateway_unstake - -.PHONY: gateway2_unstake -gateway2_unstake: ## Unstake gateway2 - GATEWAY=gateway2 make gateway_unstake - -.PHONY: gateway3_unstake -gateway3_unstake: ## Unstake gateway3 - GATEWAY=gateway3 make gateway_unstake - -#################### -### Applications ### -#################### - -.PHONY: app_list -app_list: ## List all the staked applications - poktrolld --home=$(POKTROLLD_HOME) q application list-application --node $(POCKET_NODE) - -.PHONY: app_stake -app_stake: ## Stake tokens for the application specified (must specify the APP and SERVICES env vars) - poktrolld --home=$(POKTROLLD_HOME) tx application stake-application -y --config $(POKTROLLD_HOME)/config/$(SERVICES) --keyring-backend test --from $(APP) --node $(POCKET_NODE) - -.PHONY: app1_stake -app1_stake: ## Stake app1 (also staked in genesis) - APP=app1 SERVICES=application1_stake_config.yaml make app_stake - -.PHONY: app2_stake -app2_stake: ## Stake app2 - APP=app2 SERVICES=application2_stake_config.yaml make app_stake - -.PHONY: app3_stake -app3_stake: ## Stake app3 - APP=app3 SERVICES=application3_stake_config.yaml make app_stake - -.PHONY: app_unstake -app_unstake: ## Unstake an application (must specify the APP env var) - poktrolld --home=$(POKTROLLD_HOME) tx application unstake-application -y --keyring-backend test --from $(APP) --node $(POCKET_NODE) - -.PHONY: app1_unstake -app1_unstake: ## Unstake app1 - APP=app1 make app_unstake - -.PHONY: app2_unstake -app2_unstake: ## Unstake app2 - APP=app2 make app_unstake - -.PHONY: app3_unstake -app3_unstake: ## Unstake app3 - APP=app3 make app_unstake - -.PHONY: app_delegate -app_delegate: ## Delegate trust to a gateway (must specify the APP and GATEWAY_ADDR env vars). Requires the app to be staked - poktrolld --home=$(POKTROLLD_HOME) tx application delegate-to-gateway $(GATEWAY_ADDR) --keyring-backend test --from $(APP) --node $(POCKET_NODE) - -.PHONY: app1_delegate_gateway1 -app1_delegate_gateway1: ## Delegate trust to gateway1 - GATEWAY1=$$(make poktrolld_addr ACC_NAME=gateway1) && \ - APP=app1 GATEWAY_ADDR=$$GATEWAY1 make app_delegate - -.PHONY: app2_delegate_gateway2 -app2_delegate_gateway2: ## Delegate trust to gateway2 - GATEWAY2=$$(make poktrolld_addr ACC_NAME=gateway2) && \ - APP=app2 GATEWAY_ADDR=$$GATEWAY2 make app_delegate - -.PHONY: app3_delegate_gateway3 -app3_delegate_gateway3: ## Delegate trust to gateway3 - GATEWAY3=$$(make poktrolld_addr ACC_NAME=gateway3) && \ - APP=app3 GATEWAY_ADDR=$$GATEWAY3 make app_delegate - -.PHONY: app_undelegate -app_undelegate: ## Undelegate trust to a gateway (must specify the APP and GATEWAY_ADDR env vars). Requires the app to be staked - poktrolld --home=$(POKTROLLD_HOME) tx application undelegate-from-gateway $(GATEWAY_ADDR) --keyring-backend test --from $(APP) --node $(POCKET_NODE) - -.PHONY: app1_undelegate_gateway1 -app1_undelegate_gateway1: ## Undelegate trust to gateway1 - GATEWAY1=$$(make poktrolld_addr ACC_NAME=gateway1) && \ - APP=app1 GATEWAY_ADDR=$$GATEWAY1 make app_undelegate - -.PHONY: app2_undelegate_gateway2 -app2_undelegate_gateway2: ## Undelegate trust to gateway2 - GATEWAY2=$$(make poktrolld_addr ACC_NAME=gateway2) && \ - APP=app2 GATEWAY_ADDR=$$GATEWAY2 make app_undelegate - -.PHONY: app3_undelegate_gateway3 -app3_undelegate_gateway3: ## Undelegate trust to gateway3 - GATEWAY3=$$(make poktrolld_addr ACC_NAME=gateway3) && \ - APP=app3 GATEWAY_ADDR=$$GATEWAY3 make app_undelegate - -################# -### Suppliers ### -################# - -.PHONY: supplier_list -supplier_list: ## List all the staked supplier - poktrolld --home=$(POKTROLLD_HOME) q supplier list-supplier --node $(POCKET_NODE) - -.PHONY: supplier_stake -supplier_stake: ## Stake tokens for the supplier specified (must specify the SUPPLIER and SUPPLIER_CONFIG env vars) - poktrolld --home=$(POKTROLLD_HOME) tx supplier stake-supplier -y --config $(POKTROLLD_HOME)/config/$(SERVICES) --keyring-backend test --from $(SUPPLIER) --node $(POCKET_NODE) - -.PHONY: supplier1_stake -supplier1_stake: ## Stake supplier1 (also staked in genesis) - SUPPLIER=supplier1 SERVICES=supplier1_stake_config.yaml make supplier_stake - -.PHONY: supplier2_stake -supplier2_stake: ## Stake supplier2 - SUPPLIER=supplier2 SERVICES=supplier2_stake_config.yaml make supplier_stake - -.PHONY: supplier3_stake -supplier3_stake: ## Stake supplier3 - SUPPLIER=supplier3 SERVICES=supplier3_stake_config.yaml make supplier_stake - -.PHONY: supplier_unstake -supplier_unstake: ## Unstake an supplier (must specify the SUPPLIER env var) - poktrolld --home=$(POKTROLLD_HOME) tx supplier unstake-supplier $(SUPPLIER) --keyring-backend test --from $(SUPPLIER) --node $(POCKET_NODE) - -.PHONY: supplier1_unstake -supplier1_unstake: ## Unstake supplier1 - SUPPLIER=supplier1 make supplier_unstake - -.PHONY: supplier2_unstake -supplier2_unstake: ## Unstake supplier2 - SUPPLIER=supplier2 make supplier_unstake - -.PHONY: supplier3_unstake -supplier3_unstake: ## Unstake supplier3 - SUPPLIER=supplier3 make supplier_unstake - -############### -### Session ### -############### - -.PHONY: get_session -get_session: ## Retrieve the session given the following env vars: (APP_ADDR, SVC, HEIGHT) - poktrolld --home=$(POKTROLLD_HOME) q session get-session $(APP) $(SVC) $(HEIGHT) --node $(POCKET_NODE) - -.PHONY: get_session_app1_anvil -get_session_app1_anvil: ## Retrieve the session for (app1, anvil, latest_height) - APP1=$$(make poktrolld_addr ACC_NAME=app1) && \ - APP=$$APP1 SVC=anvil HEIGHT=0 make get_session - -.PHONY: get_session_app2_anvil -get_session_app2_anvil: ## Retrieve the session for (app2, anvil, latest_height) - APP2=$$(make poktrolld_addr ACC_NAME=app2) && \ - APP=$$APP2 SVC=anvil HEIGHT=0 make get_session - -.PHONY: get_session_app3_anvil -get_session_app3_anvil: ## Retrieve the session for (app3, anvil, latest_height) - APP3=$$(make poktrolld_addr ACC_NAME=app3) && \ - APP=$$APP3 SVC=anvil HEIGHT=0 make get_session - -############### -### TestNet ### -############### - -.PHONY: testnet_supplier_list -testnet_supplier_list: ## List all the staked supplier on TestNet - poktrolld q supplier list-supplier --node=$(TESTNET_RPC) - -.PHONY: testnet_gateway_list -testnet_gateway_list: ## List all the staked gateways on TestNet - poktrolld q gateway list-gateway --node=$(TESTNET_RPC) - -.PHONY: testnet_app_list -testnet_app_list: ## List all the staked applications on TestNet - poktrolld q application list-application --node=$(TESTNET_RPC) - -.PHONY: testnet_consensus_params -testnet_consensus_params: ## Output consensus parameters - poktrolld q consensus params --node=$(TESTNET_RPC) - -.PHONY: testnet_gov_params -testnet_gov_params: ## Output gov parameters - poktrolld q gov params --node=$(TESTNET_RPC) - -.PHONY: testnet_status -testnet_status: ## Output status of the RPC node (most likely a validator) - poktrolld status --node=$(TESTNET_RPC) | jq - -.PHONY: testnet_height -testnet_height: ## Height of the network from the RPC node point of view - poktrolld status --node=$(TESTNET_RPC) | jq ".sync_info.latest_block_height" - ################ ### Accounts ### ################ @@ -833,161 +292,6 @@ acc_initialize_pubkeys: ## Make sure the account keeper has public keys for all --home=$(POKTROLLD_HOME) \ --node $(POCKET_NODE);) -######################## -### Warning Messages ### -######################## - -.PHONY: warn_message_acc_initialize_pubkeys -warn_message_acc_initialize_pubkeys: ## Print a warning message about the need to run `make acc_initialize_pubkeys` - @echo "+----------------------------------------------------------------------------------+" - @echo "| |" - @echo "| IMPORTANT: Please run the following command once to initialize |" - @echo "| E2E tests after the network has started: |" - @echo "| |" - @echo "| make acc_initialize_pubkeys |" - @echo "| |" - @echo "+----------------------------------------------------------------------------------+" - -.PHONY: warn_message_local_stress_test -warn_message_local_stress_test: ## Print a warning message when kicking off a local E2E relay stress test - @echo "+-----------------------------------------------------------------------------------------------+" - @echo "| |" - @echo "| IMPORTANT: Please read the following before continuing with the stress test. |" - @echo "| |" - @echo "| 1. Review the # of suppliers & gateways in 'load-testing/localnet_loadtest_manifest.yaml' |" - @echo "| 2. Update 'localnet_config.yaml' to reflect what you found in (1) |" - @echo "| DEVELOPER_TIP: If you're operating off defaults, you'll likely need to update to 3 |" - @echo "| |" - @echo "| TODO_DOCUMENT(@okdas): Move this into proper documentation w/ clearer explanations |" - @echo "| |" - @echo "+-----------------------------------------------------------------------------------------------+" - -PHONY: warn_flaky_tests -warn_flaky_tests: ## Print a warning message that some unit tests may be flaky - @echo "+-----------------------------------------------------------------------------------------------+" - @echo "| |" - @echo "| IMPORTANT: READ ME IF YOUR TESTS FAIL!!! |" - @echo "| |" - @echo "| 1. Our unit / integration tests are far from perfect & some are flaky |" - @echo "| 2. If you ran 'make go_develop_and_test' and a failure occurred, try to run: |" - @echo "| 'make test_all' once or twice more |" - @echo "| 3. If the same error persists, isolate it with 'go test -v ./path/to/failing/module |" - @echo "| |" - @echo "+-----------------------------------------------------------------------------------------------+" - -############## -### Claims ### -############## - -# These encoded values were generated using the `encodeSessionHeader` helpers in `query_claim_test.go` as dummy values. -ENCODED_SESSION_HEADER = "eyJhcHBsaWNhdGlvbl9hZGRyZXNzIjoicG9rdDFleXJuNDUwa3JoZnpycmVyemd0djd2c3J4bDA5NDN0dXN4azRhayIsInNlcnZpY2UiOnsiaWQiOiJhbnZpbCIsIm5hbWUiOiIifSwic2Vzc2lvbl9zdGFydF9ibG9ja19oZWlnaHQiOiI1Iiwic2Vzc2lvbl9pZCI6InNlc3Npb25faWQxIiwic2Vzc2lvbl9lbmRfYmxvY2tfaGVpZ2h0IjoiOSJ9" -ENCODED_ROOT_HASH = "cm9vdF9oYXNo" -.PHONY: claim_create_dummy -claim_create_dummy: ## Create a dummy claim by supplier1 - poktrolld --home=$(POKTROLLD_HOME) tx supplier create-claim \ - $(ENCODED_SESSION_HEADER) \ - $(ENCODED_ROOT_HASH) \ - --from supplier1 --node $(POCKET_NODE) - -.PHONY: claims_list -claim_list: ## List all the claims - poktrolld --home=$(POKTROLLD_HOME) q supplier list-claims --node $(POCKET_NODE) - -.PHONY: claims_list_address -claim_list_address: ## List all the claims for a specific address (specified via ADDR variable) - poktrolld --home=$(POKTROLLD_HOME) q supplier list-claims --supplier-operator-address $(ADDR) --node $(POCKET_NODE) - -.PHONY: claims_list_address_supplier1 -claim_list_address_supplier1: ## List all the claims for supplier1 - SUPPLIER1=$$(make poktrolld_addr ACC_NAME=supplier1) && \ - ADDR=$$SUPPLIER1 make claim_list_address - -.PHONY: claim_list_height -claim_list_height: ## List all the claims ending at a specific height (specified via HEIGHT variable) - poktrolld --home=$(POKTROLLD_HOME) q supplier list-claims --session-end-height $(HEIGHT) --node $(POCKET_NODE) - -.PHONY: claim_list_height_5 -claim_list_height_5: ## List all the claims at height 5 - HEIGHT=5 make claim_list_height - -.PHONY: claim_list_session -claim_list_session: ## List all the claims ending at a specific session (specified via SESSION variable) - poktrolld --home=$(POKTROLLD_HOME) q supplier list-claims --session-id $(SESSION) --node $(POCKET_NODE) - -############## -### Params ### -############## - -# TODO_CONSIDERATION: additional factoring (e.g. POKTROLLD_FLAGS). -PARAM_FLAGS = --home=$(POKTROLLD_HOME) --keyring-backend test --from $(PNF_ADDRESS) --node $(POCKET_NODE) - -### Tokenomics Module Params ### -.PHONY: update_tokenomics_params_all -params_update_tokenomics_all: ## Update the tokenomics module params - poktrolld tx authz exec ./tools/scripts/params/tokenomics_all.json $(PARAM_FLAGS) - -.PHONY: params_update_tokenomics_compute_units_to_tokens_multiplier -params_update_tokenomics_compute_units_to_tokens_multiplier: ## Update the tokenomics module compute_units_to_tokens_multiplier param - poktrolld tx authz exec ./tools/scripts/params/tokenomics_compute_units_to_tokens_multiplier.json $(PARAM_FLAGS) - -### Proof Module Params ### -.PHONY: params_update_proof_all -params_update_proof_all: ## Update the proof module params - poktrolld tx authz exec ./tools/scripts/params/proof_all.json $(PARAM_FLAGS) - -.PHONY: params_update_proof_min_relay_difficulty_bits -params_update_proof_min_relay_difficulty_bits: ## Update the proof module min_relay_difficulty_bits param - poktrolld tx authz exec ./tools/scripts/params/proof_min_relay_difficulty_bits.json $(PARAM_FLAGS) - -.PHONY: params_update_proof_proof_request_probability -params_update_proof_proof_request_probability: ## Update the proof module proof_request_probability param - poktrolld tx authz exec ./tools/scripts/params/proof_proof_request_probability.json $(PARAM_FLAGS) - -.PHONY: params_update_proof_proof_requirement_threshold -params_update_proof_proof_requirement_threshold: ## Update the proof module proof_requirement_threshold param - poktrolld tx authz exec ./tools/scripts/params/proof_proof_requirement_threshold.json $(PARAM_FLAGS) - -.PHONY: params_update_proof_proof_missing_penalty -params_update_proof_proof_missing_penalty: ## Update the proof module proof_missing_penalty param - poktrolld tx authz exec ./tools/scripts/params/proof_proof_missing_penalty.json $(PARAM_FLAGS) - -### Shared Module Params ### -.PHONY: params_update_shared_all -params_update_shared_all: ## Update the session module params - poktrolld tx authz exec ./tools/scripts/params/shared_all.json $(PARAM_FLAGS) - -.PHONY: params_update_shared_num_blocks_per_session -params_update_shared_num_blocks_per_session: ## Update the shared module num_blocks_per_session param - poktrolld tx authz exec ./tools/scripts/params/shared_num_blocks_per_session.json $(PARAM_FLAGS) - -.PHONY: params_update_shared_grace_period_end_offset_blocks -params_update_shared_grace_period_end_offset_blocks: ## Update the shared module grace_period_end_offset_blocks param - poktrolld tx authz exec ./tools/scripts/params/shared_grace_period_end_offset_blocks.json $(PARAM_FLAGS) - -.PHONY: params_update_shared_claim_window_open_offset_blocks -params_update_shared_claim_window_open_offset_blocks: ## Update the shared module claim_window_open_offset_blocks param - poktrolld tx authz exec ./tools/scripts/params/shared_claim_window_open_offset_blocks.json $(PARAM_FLAGS) - -.PHONY: params_update_shared_claim_window_close_offset_blocks -params_update_shared_claim_window_close_offset_blocks: ## Update the shared module claim_window_close_offset_blocks param - poktrolld tx authz exec ./tools/scripts/params/shared_claim_window_close_offset_blocks.json $(PARAM_FLAGS) - -.PHONY: params_update_shared_proof_window_open_offset_blocks -params_update_shared_proof_window_open_offset_blocks: ## Update the shared module proof_window_open_offset_blocks param - poktrolld tx authz exec ./tools/scripts/params/shared_proof_window_open_offset_blocks.json $(PARAM_FLAGS) - -.PHONY: params_update_shared_proof_window_close_offset_blocks -params_update_shared_proof_window_close_offset_blocks: ## Update the shared module proof_window_close_offset_blocks param - poktrolld tx authz exec ./tools/scripts/params/shared_proof_window_close_offset_blocks.json $(PARAM_FLAGS) - -.PHONY: params_query_all -params_query_all: check_jq ## Query the params from all available modules - @for module in $(MODULES); do \ - echo "~~~ Querying $$module module params ~~~"; \ - poktrolld query $$module params --node $(POCKET_NODE) --output json | jq; \ - echo ""; \ - done - ###################### ### Ignite Helpers ### ###################### From 44a6545d219daf0d89a13fe96153b7b99f0fb125 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 11 Nov 2024 00:39:29 +0100 Subject: [PATCH 17/55] add 204 no content for ping response --- pkg/relayer/relayminer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index ccb788837..a9d6dfe4c 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -160,6 +160,6 @@ func (rel *relayMiner) newPinghandlerFn(ctx context.Context, ln net.Listener) ht return } - w.WriteHeader(http.StatusOK) + w.WriteHeader(http.StatusNoContent) }) } From 8fdd7e9235da499147569843951f46f481d5c3c8 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 11 Nov 2024 00:44:20 +0100 Subject: [PATCH 18/55] add comments to addr for ping config --- pkg/relayer/config/types.go | 8 +++++--- pkg/relayer/proxy/proxy.go | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg/relayer/config/types.go b/pkg/relayer/config/types.go index db6660805..67a7c8071 100644 --- a/pkg/relayer/config/types.go +++ b/pkg/relayer/config/types.go @@ -29,8 +29,9 @@ type YAMLRelayMinerConfig struct { // YAMLRelayMinerPingConfig represents the configuration to expose a ping server. type YAMLRelayMinerPingConfig struct { - Enabled bool `yaml:"enabled"` - Addr string `yaml:"addr"` + Enabled bool `yaml:"enabled"` + // Addr is the address to bind to (format: 'hostname:port') + Addr string `yaml:"addr"` } // YAMLRelayMinerPocketNodeConfig is the structure used to unmarshal the pocket @@ -97,7 +98,8 @@ type RelayMinerConfig struct { // server configuration. type RelayMinerPingConfig struct { Enabled bool - Addr string + // Addr is the address to bind to (format: hostname:port) + Addr string } // RelayMinerPocketNodeConfig is the structure resulting from parsing the pocket diff --git a/pkg/relayer/proxy/proxy.go b/pkg/relayer/proxy/proxy.go index 1dac8570a..ee170d806 100644 --- a/pkg/relayer/proxy/proxy.go +++ b/pkg/relayer/proxy/proxy.go @@ -152,6 +152,7 @@ func (rp *relayerProxy) Start(ctx context.Context) error { if err := rp.BuildProvidedServices(ctx); err != nil { return err } + // Start the ring cache. rp.ringCache.Start(ctx) From f9d636e364f82b87147aa2a6cfbaa7f05167e3c3 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 11 Nov 2024 00:51:05 +0100 Subject: [PATCH 19/55] revert Makefile --- Makefile | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/Makefile b/Makefile index 71d0b2a44..fcdb6ec87 100644 --- a/Makefile +++ b/Makefile @@ -170,28 +170,6 @@ proto_clean_pulsar: ## TODO_TECHDEBT(@bryanchriswhite): Add a proper explanation .PHONY: proto_regen proto_regen: proto_clean proto_ignite_gen proto_fix_self_import ## Regenerate protobuf artifacts -######################## -### Localnet Helpers ### -######################## - -.PHONY: localnet_relayminer1_ping -localnet_relayminer1_ping: - @echo "Pinging relayminer 1..." - @curl -X GET localhost:7001 || (echo "Failed to ping relayminer1. Make sure your localnet environment or your relayminer pod is up and running"; exit 1) - @echo "OK" - -.PHONY: localnet_relayminer2_ping -localnet_relayminer2_ping: - @echo "Pinging relayminer 2..." - @curl -X GET localhost:7002 || (echo "Failed to ping relayminer2. Make sure your localnet environment or your relayminer pod is up and running"; exit 1) - @echo "OK" - -.PHONY: localnet_relayminer3_ping -localnet_relayminer3_ping: - @echo "Pinging relayminer 3..." - @curl -X GET localhost:7003 || (echo "Failed to ping relayminer3. Make sure your localnet environment or your relayminer pod is up and running"; exit 1) - @echo "OK" - ####################### ### Docker Helpers ### ####################### From d94ead27bf65da0817b7f34d48da68fe614cb954 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 11 Nov 2024 00:53:30 +0100 Subject: [PATCH 20/55] fix typo --- docusaurus/docs/operate/configs/relayminer_config.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docusaurus/docs/operate/configs/relayminer_config.md b/docusaurus/docs/operate/configs/relayminer_config.md index 0f5733afe..5c68bc705 100644 --- a/docusaurus/docs/operate/configs/relayminer_config.md +++ b/docusaurus/docs/operate/configs/relayminer_config.md @@ -176,9 +176,9 @@ You can learn how to use that endpoint on the [Performance Troubleshooting](../. ### `ping` -Configures a `ping` server to test the connectivity of every backend URLs. If -all the backend URLs are reachable, the endpoint returns a 200 HTTP -Code. Otherwise, if one or more backend URLs aren't reachable, the service +Configures a `ping` server to test the connectivity of all backend URLs. If +all the backend URLs are reachable, the endpoint returns a 204 HTTP +Code. If one or more backend URLs aren't reachable, the service returns an 500 HTTP Internal server error. Example configuration: @@ -544,4 +544,4 @@ can disrupt the operator’s participation in the Pocket Network. To maintain a smooth operation, avoid being slashed, and earn your rewards, operators must plan and manage their account balance as part of their operational procedures. -::: \ No newline at end of file +::: From 5153493df8ab35b92aff170794bd4a44a9338a15 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 11 Nov 2024 00:56:32 +0100 Subject: [PATCH 21/55] add statuscode assertion while testing ping server --- pkg/relayer/relayminer_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index bdba36d33..ecfcdcfbc 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -121,9 +121,11 @@ func TestRelayMiner_Ping(t *testing.T) { } require.NoError(t, err) - _, err = c.Get("http://unix") + resp, err := c.Get("http://unix") require.NoError(t, err) + require.Equal(t, http.StatusNoContent, resp.StatusCode) + err = relayminer.Stop(ctx) require.NoError(t, err) } From 861bf351954bb1d4018aec19aea6b468d809d5d3 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 11 Nov 2024 14:24:57 +0100 Subject: [PATCH 22/55] add localnet helpers to ping relayminer 1 2 3 + port exposition --- Makefile | 23 +++++++++++++++++++++++ Tiltfile | 6 ++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index fcdb6ec87..5330a6fdb 100644 --- a/Makefile +++ b/Makefile @@ -170,6 +170,29 @@ proto_clean_pulsar: ## TODO_TECHDEBT(@bryanchriswhite): Add a proper explanation .PHONY: proto_regen proto_regen: proto_clean proto_ignite_gen proto_fix_self_import ## Regenerate protobuf artifacts +######################## +### Localnet Helpers ### +######################## + +.PHONY: localnet_relayminer1_ping +localnet_relayminer1_ping: + @echo "Pinging relayminer 1..." + @curl -X GET localhost:7001 || (echo "Failed to ping relayminer1. Make sure your localnet environment or the relayminer 1 pod is up and running"; exit 1) + @echo "OK" + +.PHONY: localnet_relayminer2_ping +localnet_relayminer2_ping: + @echo "Pinging relayminer 2..." + @curl -X GET localhost:7002 || (echo "Failed to ping relayminer2. Make sure your localnet environment or the relayminer 2 pod is up and running"; exit 1) + @echo "OK" + +.PHONY: localnet_relayminer3_ping +localnet_relayminer3_ping: + @echo "Pinging relayminer 3..." + @curl -X GET localhost:7003 || (echo "Failed to ping relayminer3. Make sure your localnet environment or the relayminer 3 pod is up and running"; exit 1) + @echo "OK" + + ####################### ### Docker Helpers ### ####################### diff --git a/Tiltfile b/Tiltfile index 9a104a3d2..5f4c81b97 100644 --- a/Tiltfile +++ b/Tiltfile @@ -265,7 +265,7 @@ actor_number = 0 for x in range(localnet_config["relayminers"]["count"]): actor_number = actor_number + 1 - flags = [ + flags=[ "--values=./localnet/kubernetes/values-common.yaml", "--values=./localnet/kubernetes/values-relayminer-common.yaml", "--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + ".yaml", @@ -273,15 +273,12 @@ for x in range(localnet_config["relayminers"]["count"]): "--set=development.delve.enabled=" + str(localnet_config["relayminers"]["delve"]["enabled"]), "--set=logLevel=" + str(localnet_config["relayminers"]["logs"]["level"]), "--set=image.repository=poktrolld", - ], ] if localnet_config["rest"]["enabled"]: flags.append("--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + "-rest" + ".yaml") - if localnet_config["ollama"]["enabled"]: flags.append("--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + "-ollama" + ".yaml") - if localnet_config["rest"]["enabled"] and localnet_config["ollama"]["enabled"]: flags.append("--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + "-all" + ".yaml") @@ -292,6 +289,7 @@ for x in range(localnet_config["relayminers"]["count"]): image_deps=["poktrolld"], image_keys=[("image.repository", "image.tag")], ) + k8s_resource( "relayminer" + str(actor_number), labels=["suppliers"], From 4802e86228673c7d504cdde215046794e6a2e1c3 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Thu, 14 Nov 2024 08:06:33 +0100 Subject: [PATCH 23/55] add more context to synchrounous rpc ping error --- pkg/relayer/proxy/synchronous.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/relayer/proxy/synchronous.go b/pkg/relayer/proxy/synchronous.go index d3f2ee7d6..93bc921b8 100644 --- a/pkg/relayer/proxy/synchronous.go +++ b/pkg/relayer/proxy/synchronous.go @@ -109,7 +109,9 @@ func (sync *synchronousRPCServer) Ping(ctx context.Context) error { _ = resp.Body.Close() if resp.StatusCode >= http.StatusInternalServerError { - return ErrRelayerProxySupplierNotReachable + return ErrRelayerProxySupplierNotReachable.Wrapf( + "endpoint URL %q err: %s", + supplierCfg.ServiceConfig.BackendUrl.String(), err) } } From fda1da318785fa9d9bc594e66181c82f7cb8cdfb Mon Sep 17 00:00:00 2001 From: eddyzags Date: Thu, 14 Nov 2024 08:08:05 +0100 Subject: [PATCH 24/55] change c to httpClient in relayminer tests --- pkg/relayer/relayminer_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index ecfcdcfbc..2ab7a705d 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -112,7 +112,7 @@ func TestRelayMiner_Ping(t *testing.T) { time.Sleep(time.Millisecond) - c := http.Client{ + httpClient := http.Client{ Transport: &http.Transport{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { return net.Dial(ln.Addr().Network(), ln.Addr().String()) @@ -121,7 +121,7 @@ func TestRelayMiner_Ping(t *testing.T) { } require.NoError(t, err) - resp, err := c.Get("http://unix") + resp, err := httpClient.Get("http://unix") require.NoError(t, err) require.Equal(t, http.StatusNoContent, resp.StatusCode) From 499ee4ecd8b323b305d04358b4852dab77528397 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Thu, 14 Nov 2024 08:09:07 +0100 Subject: [PATCH 25/55] add more context to transport override in relayminer tests --- pkg/relayer/relayminer_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index 2ab7a705d..4466e2af0 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -112,6 +112,7 @@ func TestRelayMiner_Ping(t *testing.T) { time.Sleep(time.Millisecond) + // Override transport configuration to adapt the http client to the unix socket listener. httpClient := http.Client{ Transport: &http.Transport{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { From 26dad58fdf104995c0a71c14f213114f028e5bb1 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 13 Jan 2025 00:14:58 +0100 Subject: [PATCH 26/55] add transport varialbe in relayminer tests --- pkg/relayer/relayminer_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index 4466e2af0..1a429aace 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -112,14 +112,14 @@ func TestRelayMiner_Ping(t *testing.T) { time.Sleep(time.Millisecond) - // Override transport configuration to adapt the http client to the unix socket listener. - httpClient := http.Client{ - Transport: &http.Transport{ - DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - return net.Dial(ln.Addr().Network(), ln.Addr().String()) - }, + transport := &http.Transport{ + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + return net.Dial(ln.Addr().Network(), ln.Addr().String()) }, } + + // Override transport configuration to adapt the http client to the unix socket listener. + httpClient := http.Client{Transport: transport} require.NoError(t, err) resp, err := httpClient.Get("http://unix") From 3d5128d61a0d819022dc45a858074fed54fd897c Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 13 Jan 2025 00:27:13 +0100 Subject: [PATCH 27/55] add 502 bad gateway as http code response for /ping --- pkg/relayer/relayminer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index a9d6dfe4c..2b22fb579 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -156,7 +156,7 @@ func (rel *relayMiner) newPinghandlerFn(ctx context.Context, ln net.Listener) ht rel.logger.Debug().Msg("pinging relay servers...") if err := rel.relayerProxy.PingAll(ctx); err != nil { - w.WriteHeader(http.StatusInternalServerError) + w.WriteHeader(http.StatusBadGateway) return } From 970998360cc024f8e3f4db86de1c89b5e58ecb61 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 13 Jan 2025 00:57:59 +0100 Subject: [PATCH 28/55] add tcp listener to relayerminer pkg --- pkg/relayer/cmd/cmd.go | 8 ++------ pkg/relayer/relayminer.go | 9 +++++++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/pkg/relayer/cmd/cmd.go b/pkg/relayer/cmd/cmd.go index 749f06627..909897a4a 100644 --- a/pkg/relayer/cmd/cmd.go +++ b/pkg/relayer/cmd/cmd.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "net" "net/http" "net/url" "os" @@ -141,12 +140,9 @@ func runRelayer(cmd *cobra.Command, _ []string) error { } if relayMinerConfig.Ping.Enabled { - ln, err := net.Listen("tcp", relayMinerConfig.Ping.Addr) - if err != nil { - return fmt.Errorf("failed to listen ping server: %w", err) + if err := relayMiner.ServePing(ctx, relayMinerConfig.Ping.Addr); err != nil { + return fmt.Errorf("failed to start ping endpoint: %w", err) } - - relayMiner.ServePing(ctx, ln) } // Start the relay miner diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index 2b22fb579..86d541abd 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -138,7 +138,12 @@ func (rel *relayMiner) ServePprof(ctx context.Context, addr string) error { // ServePing exposes ping HTTP server to check the reachability between the // relay miner and its dependencies (Ex: relay server and their respective // backend URLs). -func (rel *relayMiner) ServePing(ctx context.Context, ln net.Listener) { +func (rel *relayMiner) ServePing(ctx context.Context, addr string) error { + ln, err := net.Listen("tcp", addr) + if err != nil { + return err + } + // Start a long-lived goroutine that starts an HTTP server responding to // ping requests. A single ping request on the relay server broadcasts a // ping to all backing services/data nodes. @@ -148,7 +153,7 @@ func (rel *relayMiner) ServePing(ctx context.Context, ln net.Listener) { } }() - return + return nil } func (rel *relayMiner) newPinghandlerFn(ctx context.Context, ln net.Listener) http.HandlerFunc { From e3ed522914f1c1a1c43fcf6050a92085550df8f7 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 13 Jan 2025 22:09:13 +0100 Subject: [PATCH 29/55] fix code registration for ErrRelayerProxySupplierNotReachable --- pkg/relayer/proxy/errors.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/relayer/proxy/errors.go b/pkg/relayer/proxy/errors.go index f52544f21..f940c3f13 100644 --- a/pkg/relayer/proxy/errors.go +++ b/pkg/relayer/proxy/errors.go @@ -20,5 +20,5 @@ var ( ErrRelayerProxyUnknownSession = sdkerrors.Register(codespace, 12, "relayer proxy encountered unknown session") ErrRelayerProxyRateLimited = sdkerrors.Register(codespace, 13, "offchain rate limit hit by relayer proxy") ErrRelayerProxyUnclaimRelayPrice = sdkerrors.Register(codespace, 14, "failed to unclaim relay price") - ErrRelayerProxySupplierNotReachable = sdkerrors.Register(codespace, 12, "supplier(s) not reachable") + ErrRelayerProxySupplierNotReachable = sdkerrors.Register(codespace, 15, "supplier(s) not reachable") ) From 8130cf3b018587564f1856915961815da15d0e69 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 13 Jan 2025 22:34:37 +0100 Subject: [PATCH 30/55] add endpointURL variable --- pkg/relayer/proxy/synchronous.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/relayer/proxy/synchronous.go b/pkg/relayer/proxy/synchronous.go index 93bc921b8..f971cdb5a 100644 --- a/pkg/relayer/proxy/synchronous.go +++ b/pkg/relayer/proxy/synchronous.go @@ -101,8 +101,9 @@ func (sync *synchronousRPCServer) Stop(ctx context.Context) error { func (sync *synchronousRPCServer) Ping(ctx context.Context) error { for _, supplierCfg := range sync.serverConfig.SupplierConfigsMap { httpClient := &http.Client{Timeout: 2 * time.Second} + endpointURL := supplierCfg.ServiceConfig.BackendUrl.String() - resp, err := httpClient.Head(supplierCfg.ServiceConfig.BackendUrl.String()) + resp, err := httpClient.Head(endpointURL) if err != nil { return err } From c164306e6f91760874550200a12aece856da6279 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 13 Jan 2025 22:36:21 +0100 Subject: [PATCH 31/55] improve godoc comments for pingconfig --- pkg/relayer/config/types.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/relayer/config/types.go b/pkg/relayer/config/types.go index 67a7c8071..b81ba8b5f 100644 --- a/pkg/relayer/config/types.go +++ b/pkg/relayer/config/types.go @@ -30,7 +30,7 @@ type YAMLRelayMinerConfig struct { // YAMLRelayMinerPingConfig represents the configuration to expose a ping server. type YAMLRelayMinerPingConfig struct { Enabled bool `yaml:"enabled"` - // Addr is the address to bind to (format: 'hostname:port') + // Addr is the address to bind to (format: 'hostname:port') where 'hostname' can be a DNS name or an IP Addr string `yaml:"addr"` } @@ -98,7 +98,7 @@ type RelayMinerConfig struct { // server configuration. type RelayMinerPingConfig struct { Enabled bool - // Addr is the address to bind to (format: hostname:port) + // Addr is the address to bind to (format: hostname:port) where 'hostname' can be a DNS name or an IP Addr string } From 239f2f177faaede40ef9579a71de1f7ab7ea7e3e Mon Sep 17 00:00:00 2001 From: eddyzags Date: Thu, 16 Jan 2025 21:35:23 +0100 Subject: [PATCH 32/55] fix serveping tests + refactor relayminer.ServePing function signature --- pkg/relayer/cmd/cmd.go | 2 +- pkg/relayer/relayminer.go | 10 ++++++++-- pkg/relayer/relayminer_test.go | 7 ++----- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/pkg/relayer/cmd/cmd.go b/pkg/relayer/cmd/cmd.go index 909897a4a..b73ce1984 100644 --- a/pkg/relayer/cmd/cmd.go +++ b/pkg/relayer/cmd/cmd.go @@ -140,7 +140,7 @@ func runRelayer(cmd *cobra.Command, _ []string) error { } if relayMinerConfig.Ping.Enabled { - if err := relayMiner.ServePing(ctx, relayMinerConfig.Ping.Addr); err != nil { + if err := relayMiner.ServePing(ctx, "tcp", relayMinerConfig.Ping.Addr); err != nil { return fmt.Errorf("failed to start ping endpoint: %w", err) } } diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index 86d541abd..45e997f76 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -138,8 +138,8 @@ func (rel *relayMiner) ServePprof(ctx context.Context, addr string) error { // ServePing exposes ping HTTP server to check the reachability between the // relay miner and its dependencies (Ex: relay server and their respective // backend URLs). -func (rel *relayMiner) ServePing(ctx context.Context, addr string) error { - ln, err := net.Listen("tcp", addr) +func (rel *relayMiner) ServePing(ctx context.Context, network, addr string) error { + ln, err := net.Listen(network, addr) if err != nil { return err } @@ -153,6 +153,12 @@ func (rel *relayMiner) ServePing(ctx context.Context, addr string) error { } }() + go func() { + <-ctx.Done() + rel.logger.Info().Str("endpoint", addr).Msg("stopping ping server") + _ = ln.Close() + }() + return nil } diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index 1a429aace..286bc6260 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -104,17 +104,14 @@ func TestRelayMiner_Ping(t *testing.T) { filename := "/tmp/relayerminer.ping.sock" - ln, err := net.Listen("unix", filename) - require.NoError(t, err) + relayminer.ServePing(ctx, "unix", filename) defer os.Remove(filename) - relayminer.ServePing(ctx, ln) - time.Sleep(time.Millisecond) transport := &http.Transport{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - return net.Dial(ln.Addr().Network(), ln.Addr().String()) + return net.Dial("unix", "/tmp/relayerminer.ping.sock") }, } From 385b7e9e4e08eed455cae1beda198cdb5d2cf73b Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sat, 18 Jan 2025 20:11:14 +0100 Subject: [PATCH 33/55] refactor: dynamically set values for relayminer suppliers list in Tiltfile --- Tiltfile | 23 +++++++++++++++---- .../kubernetes/values-relayminer-1-all.yaml | 20 ---------------- .../values-relayminer-1-ollama.yaml | 14 ----------- .../kubernetes/values-relayminer-1-rest.yaml | 14 ----------- localnet/kubernetes/values-relayminer-1.yaml | 8 +------ .../values-relayminer-2-ollama.yaml | 14 ----------- localnet/kubernetes/values-relayminer-2.yaml | 8 +------ .../values-relayminer-3-ollama.yaml | 14 ----------- localnet/kubernetes/values-relayminer-3.yaml | 8 +------ 9 files changed, 22 insertions(+), 101 deletions(-) delete mode 100644 localnet/kubernetes/values-relayminer-1-all.yaml delete mode 100644 localnet/kubernetes/values-relayminer-1-ollama.yaml delete mode 100644 localnet/kubernetes/values-relayminer-1-rest.yaml delete mode 100644 localnet/kubernetes/values-relayminer-2-ollama.yaml delete mode 100644 localnet/kubernetes/values-relayminer-3-ollama.yaml diff --git a/Tiltfile b/Tiltfile index 5f4c81b97..9e4d9f0be 100644 --- a/Tiltfile +++ b/Tiltfile @@ -275,12 +275,27 @@ for x in range(localnet_config["relayminers"]["count"]): "--set=image.repository=poktrolld", ] + supplier_number = 0 + + flags.append("--set=config.suppliers["+str(supplier_number)+"].service_id=anvil") + flags.append("--set=config.suppliers["+str(supplier_number)+"].listen_url=http://0.0.0.0:8545") + flags.append("--set=config.suppliers["+str(supplier_number)+"].service_config.backend_url=http://anvil:8547/") + flags.append("--set=config.suppliers["+str(supplier_number)+"].service_config.publicly_exposed_endpoints[0]=relayminer"+str(actor_number)) + supplier_number = supplier_number + 1 + if localnet_config["rest"]["enabled"]: - flags.append("--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + "-rest" + ".yaml") + flags.append("--set=config.suppliers["+str(supplier_number)+"].service_id=rest") + flags.append("--set=config.suppliers["+str(supplier_number)+"].listen_url=http://0.0.0.0:8545") + flags.append("--set=config.suppliers["+str(supplier_number)+"].service_config.backend_url=http://rest:10000/") + flags.append("--set=config.suppliers["+str(supplier_number)+"].service_config.publicly_exposed_endpoints[0]=relayminer"+str(actor_number)) + supplier_number = supplier_number + 1 + if localnet_config["ollama"]["enabled"]: - flags.append("--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + "-ollama" + ".yaml") - if localnet_config["rest"]["enabled"] and localnet_config["ollama"]["enabled"]: - flags.append("--values=./localnet/kubernetes/values-relayminer-" + str(actor_number) + "-all" + ".yaml") + flags.append("--set=config.suppliers["+str(supplier_number)+"].service_id=ollama") + flags.append("--set=config.suppliers["+str(supplier_number)+"].listen_url=http://0.0.0.0:8545") + flags.append("--set=config.suppliers["+str(supplier_number)+"].service_config.backend_url=http://ollama:11434/") + flags.append("--set=config.suppliers["+str(supplier_number)+"].service_config.publicly_exposed_endpoints[0]=relayminer"+str(actor_number)) + supplier_number = supplier_number + 1 helm_resource( "relayminer" + str(actor_number), diff --git a/localnet/kubernetes/values-relayminer-1-all.yaml b/localnet/kubernetes/values-relayminer-1-all.yaml deleted file mode 100644 index 4b5bb730e..000000000 --- a/localnet/kubernetes/values-relayminer-1-all.yaml +++ /dev/null @@ -1,20 +0,0 @@ -config: - suppliers: - - service_id: anvil - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://anvil:8547/ - publicly_exposed_endpoints: - - relayminer1 - - service_id: rest - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://rest:10000/ - publicly_exposed_endpoints: - - relayminer1 - - service_id: ollama - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://ollama:11434/ - publicly_exposed_endpoints: - - relayminer1 diff --git a/localnet/kubernetes/values-relayminer-1-ollama.yaml b/localnet/kubernetes/values-relayminer-1-ollama.yaml deleted file mode 100644 index eb90af154..000000000 --- a/localnet/kubernetes/values-relayminer-1-ollama.yaml +++ /dev/null @@ -1,14 +0,0 @@ -config: - suppliers: - - service_id: anvil - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://anvil:8547/ - publicly_exposed_endpoints: - - relayminer1 - - service_id: ollama - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://ollama:11434/ - publicly_exposed_endpoints: - - relayminer1 diff --git a/localnet/kubernetes/values-relayminer-1-rest.yaml b/localnet/kubernetes/values-relayminer-1-rest.yaml deleted file mode 100644 index ca68d24ea..000000000 --- a/localnet/kubernetes/values-relayminer-1-rest.yaml +++ /dev/null @@ -1,14 +0,0 @@ -config: - suppliers: - - service_id: anvil - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://anvil:8547/ - publicly_exposed_endpoints: - - relayminer1 - - service_id: rest - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://rest:10000/ - publicly_exposed_endpoints: - - relayminer1 diff --git a/localnet/kubernetes/values-relayminer-1.yaml b/localnet/kubernetes/values-relayminer-1.yaml index 35cc0240e..0a365afe9 100644 --- a/localnet/kubernetes/values-relayminer-1.yaml +++ b/localnet/kubernetes/values-relayminer-1.yaml @@ -4,10 +4,4 @@ config: signing_key_name: supplier1 default_signing_key_names: [supplier1] - suppliers: - - service_id: anvil - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://anvil:8547/ - publicly_exposed_endpoints: - - relayminer1 + suppliers: [] # suppliers list is dynamically defined in poktroll/Tiltfile. diff --git a/localnet/kubernetes/values-relayminer-2-ollama.yaml b/localnet/kubernetes/values-relayminer-2-ollama.yaml deleted file mode 100644 index 21957cd08..000000000 --- a/localnet/kubernetes/values-relayminer-2-ollama.yaml +++ /dev/null @@ -1,14 +0,0 @@ -config: - suppliers: - - service_id: anvil - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://anvil:8547/ - publicly_exposed_endpoints: - - relayminer2 - - service_id: ollama - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://ollama:11434/ - publicly_exposed_endpoints: - - relayminer2 diff --git a/localnet/kubernetes/values-relayminer-2.yaml b/localnet/kubernetes/values-relayminer-2.yaml index 2110bc000..2d67535b5 100644 --- a/localnet/kubernetes/values-relayminer-2.yaml +++ b/localnet/kubernetes/values-relayminer-2.yaml @@ -4,10 +4,4 @@ config: signing_key_name: supplier2 default_signing_key_names: [supplier2] - suppliers: - - service_id: anvil - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://anvil:8547/ - publicly_exposed_endpoints: - - relayminer2 + suppliers: [] # suppliers list is dynamically defined in poktroll/Tiltfile. diff --git a/localnet/kubernetes/values-relayminer-3-ollama.yaml b/localnet/kubernetes/values-relayminer-3-ollama.yaml deleted file mode 100644 index f585f0066..000000000 --- a/localnet/kubernetes/values-relayminer-3-ollama.yaml +++ /dev/null @@ -1,14 +0,0 @@ -config: - suppliers: - - service_id: anvil - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://anvil:8547/ - publicly_exposed_endpoints: - - relayminer3 - - service_id: ollama - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://ollama:11434/ - publicly_exposed_endpoints: - - relayminer3 diff --git a/localnet/kubernetes/values-relayminer-3.yaml b/localnet/kubernetes/values-relayminer-3.yaml index 5a9cf0ec8..e6b21ad0a 100644 --- a/localnet/kubernetes/values-relayminer-3.yaml +++ b/localnet/kubernetes/values-relayminer-3.yaml @@ -4,10 +4,4 @@ config: signing_key_name: supplier3 default_signing_key_names: [supplier3] - suppliers: - - service_id: anvil - listen_url: http://0.0.0.0:8545 - service_config: - backend_url: http://anvil:8547/ - publicly_exposed_endpoints: - - relayminer3 + suppliers: [] # suppliers list is dynamically defined in poktroll/Tiltfile. From ad0f0a7e63203bb48d4ad3637f2845b93d7839a9 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 19 Jan 2025 23:18:43 +0100 Subject: [PATCH 34/55] add pingall test suite --- pkg/relayer/proxy/proxy.go | 4 +- pkg/relayer/proxy/proxy_test.go | 409 +++++++++++++++++++++++++++++ testutil/testproxy/relayerproxy.go | 34 +++ 3 files changed, 445 insertions(+), 2 deletions(-) diff --git a/pkg/relayer/proxy/proxy.go b/pkg/relayer/proxy/proxy.go index ee170d806..5751e2746 100644 --- a/pkg/relayer/proxy/proxy.go +++ b/pkg/relayer/proxy/proxy.go @@ -220,8 +220,8 @@ func (rp *relayerProxy) PingAll(ctx context.Context) error { var err error for _, srv := range rp.servers { - if err := srv.Ping(ctx); err != nil { - err = errors.Join(err, err) + if e := srv.Ping(ctx); e != nil { + err = errors.Join(err, e) } } diff --git a/pkg/relayer/proxy/proxy_test.go b/pkg/relayer/proxy/proxy_test.go index 7594140ee..f260894bd 100644 --- a/pkg/relayer/proxy/proxy_test.go +++ b/pkg/relayer/proxy/proxy_test.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdktypes "github.com/pokt-network/shannon-sdk/types" "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" "github.com/pokt-network/poktroll/pkg/relayer/config" "github.com/pokt-network/poktroll/pkg/relayer/proxy" @@ -554,6 +555,414 @@ func TestRelayerProxy_Relays(t *testing.T) { } } +type RelayProxyPingAllSuite struct { + suite.Suite + relayerProxyBehavior []func(*testproxy.TestBehavior) + servicesConfigMap map[string]*config.RelayMinerServerConfig + supplierEndpoints map[string][]*sharedtypes.SupplierEndpoint + supplierOperatorPingAllKeyName string + defaultRelayMinerServerAddress string + defaultServiceName string +} + +func TestRelayProxyPingAllSuite(t *testing.T) { + suite.Run(t, new(RelayProxyPingAllSuite)) +} + +// SetupSuite setups a single default relayminer with one supplier. +func (t *RelayProxyPingAllSuite) SetupSuite() { + t.supplierOperatorPingAllKeyName = "supplierPingAllKeyName" + appPrivateKey := secp256k1.GenPrivKey() + t.defaultRelayMinerServerAddress = "127.0.0.1:8245" + t.defaultServiceName = "defaultService" + + t.supplierEndpoints = map[string][]*sharedtypes.SupplierEndpoint{ + t.defaultServiceName: { + { + Url: "http://supplier1pingall:8645", + RpcType: sharedtypes.RPCType_JSON_RPC, + }, + }, + } + + t.servicesConfigMap = map[string]*config.RelayMinerServerConfig{ + t.defaultRelayMinerServerAddress: { + ServerType: config.RelayMinerServerTypeHTTP, + ListenAddress: t.defaultRelayMinerServerAddress, + SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ + t.defaultServiceName: { + ServiceId: t.defaultServiceName, + ServerType: config.RelayMinerServerTypeHTTP, + ServiceConfig: &config.RelayMinerSupplierServiceConfig{ + BackendUrl: &url.URL{ + Scheme: "http", + Host: "127.0.0.1:8645", + Path: "/", + }, + }, + PubliclyExposedEndpoints: []string{ + "supplier1pingall", + }, + }, + }, + }, + } + + t.relayerProxyBehavior = []func(*testproxy.TestBehavior){ + testproxy.WithRelayerProxyDependenciesForBlockHeight(t.supplierOperatorPingAllKeyName, 1), + testproxy.WithServicesConfigMap(t.servicesConfigMap), + testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, t.supplierEndpoints), + testproxy.WithDefaultApplication(appPrivateKey), + testproxy.WithDefaultSessionSupplier(t.supplierOperatorPingAllKeyName, t.defaultServiceName, appPrivateKey), + testproxy.WithRelayMeter(), + } +} + +func (t *RelayProxyPingAllSuite) TestOKPingAllWithSingleRelayServer() { + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() + + testBehavoirs := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), t.relayerProxyBehavior...) + + rp, err := proxy.NewRelayerProxy( + testBehavoirs.Deps, + proxy.WithSigningKeyNames([]string{t.supplierOperatorPingAllKeyName}), + proxy.WithServicesConfigMap(t.servicesConfigMap), + ) + require.NoError(t.T(), err) + + go func() { + err := rp.Start(ctx) + if http.ErrServerClosed != err { + require.NoError(t.T(), err) + } + + }() + + time.Sleep(time.Millisecond) + + err = rp.PingAll(ctx) + require.NoError(t.T(), err) + + err = rp.Stop(ctx) + require.NoError(t.T(), err) +} + +func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() + + secondServiceName := "secondService" + secondServiceAddr := "127.0.0.1:8246" + + // adding supplier endpoint. + supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ + secondServiceName: { + { + Url: "http://secondservice:8646", + RpcType: sharedtypes.RPCType_JSON_RPC, + }, + }, + } + + servicesConfigMap := map[string]*config.RelayMinerServerConfig{ + secondServiceAddr: { + ServerType: config.RelayMinerServerTypeHTTP, + ListenAddress: secondServiceAddr, + SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ + secondServiceName: { + ServiceId: secondServiceName, + ServerType: config.RelayMinerServerTypeHTTP, + ServiceConfig: &config.RelayMinerSupplierServiceConfig{ + BackendUrl: &url.URL{ + Scheme: "http", + Host: "127.0.0.1:8646", + Path: "/", + }, + }, + PubliclyExposedEndpoints: []string{ + "secondservice", + }, + }, + }, + }, + } + + relayProxyBehavior := append(t.relayerProxyBehavior, []func(*testproxy.TestBehavior){ + testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), + testproxy.WithServicesConfigMap(servicesConfigMap), + }...) + + testBehavoirs := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), relayProxyBehavior...) + + // copying default service config map + for k, v := range t.servicesConfigMap { + servicesConfigMap[k] = v + } + + rp, err := proxy.NewRelayerProxy( + testBehavoirs.Deps, + proxy.WithSigningKeyNames([]string{t.supplierOperatorPingAllKeyName}), + proxy.WithServicesConfigMap(servicesConfigMap), + ) + require.NoError(t.T(), err) + + go func() { + err := rp.Start(ctx) + if err != http.ErrServerClosed { + require.NoError(t.T(), err) + } + }() + + time.Sleep(time.Millisecond) + + err = rp.PingAll(ctx) + require.NoError(t.T(), err) + + err = rp.Stop(ctx) + require.NoError(t.T(), err) +} + +func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAtStartup() { + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() + + failingServiceName := "failingservice" + failingServiceAddr := "127.0.0.1:8247" + + supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ + failingServiceName: { + { + Url: "http://failingservice:8647", + RpcType: sharedtypes.RPCType_JSON_RPC, + }, + }, + } + + servicesConfigMap := map[string]*config.RelayMinerServerConfig{ + failingServiceAddr: &config.RelayMinerServerConfig{ + ListenAddress: failingServiceAddr, + ServerType: config.RelayMinerServerTypeHTTP, + SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ + failingServiceName: &config.RelayMinerSupplierConfig{ + ServerType: config.RelayMinerServerTypeHTTP, + ServiceId: failingServiceName, + ServiceConfig: &config.RelayMinerSupplierServiceConfig{ + BackendUrl: &url.URL{ + Scheme: "http", + Host: "127.0.0.1:8647", + Path: "/", + }, + }, + PubliclyExposedEndpoints: []string{ + "failingservice", + }, + }, + }, + }, + } + + relayProxyBehavior := append(t.relayerProxyBehavior, []func(*testproxy.TestBehavior){ + testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), + testproxy.WithServicesConfigMap(servicesConfigMap), + }...) + + test := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), relayProxyBehavior...) + + // copying services config maps from default values + for k, v := range t.servicesConfigMap { + servicesConfigMap[k] = v + } + + rp, err := proxy.NewRelayerProxy( + test.Deps, + proxy.WithSigningKeyNames([]string{t.supplierOperatorPingAllKeyName}), + proxy.WithServicesConfigMap(servicesConfigMap), + ) + require.NoError(t.T(), err) + + err = test.ShutdownServiceID(failingServiceName) + require.NoError(t.T(), err) + + err = rp.Start(ctx) + require.Error(t.T(), err) + require.True(t.T(), strings.Contains(err.Error(), "connection refused")) + + err = rp.Stop(ctx) + require.NoError(t.T(), err) +} + +func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() { + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() + + failingServiceName := "faillingservice" + failingServiceAddr := "127.0.0.1:8248" + + supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ + failingServiceName: { + { + Url: "http://failingservice:8647", + RpcType: sharedtypes.RPCType_JSON_RPC, + }, + }, + } + + servicesConfigMap := map[string]*config.RelayMinerServerConfig{ + failingServiceAddr: &config.RelayMinerServerConfig{ + ListenAddress: failingServiceAddr, + ServerType: config.RelayMinerServerTypeHTTP, + SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ + failingServiceName: &config.RelayMinerSupplierConfig{ + ServerType: config.RelayMinerServerTypeHTTP, + ServiceId: failingServiceName, + ServiceConfig: &config.RelayMinerSupplierServiceConfig{ + BackendUrl: &url.URL{ + Scheme: "http", + Host: "127.0.0.1:8647", + Path: "/", + }, + }, + PubliclyExposedEndpoints: []string{ + "failingservice", + }, + }, + }, + }, + } + + relayProxyBehavior := append(t.relayerProxyBehavior, []func(*testproxy.TestBehavior){ + testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), + testproxy.WithServicesConfigMap(servicesConfigMap), + }...) + + test := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), relayProxyBehavior...) + + // copying services config maps from default values + for k, v := range t.servicesConfigMap { + servicesConfigMap[k] = v + } + + rp, err := proxy.NewRelayerProxy( + test.Deps, + proxy.WithSigningKeyNames([]string{t.supplierOperatorPingAllKeyName}), + proxy.WithServicesConfigMap(servicesConfigMap), + ) + require.NoError(t.T(), err) + + go func() { + err := rp.Start(ctx) + if err != http.ErrServerClosed { + require.NoError(t.T(), err) + } + }() + + time.Sleep(time.Millisecond) + + err = test.ShutdownServiceID(failingServiceName) + require.NoError(t.T(), err) + + err = rp.PingAll(ctx) + require.Error(t.T(), err) + require.True(t.T(), strings.Contains(err.Error(), "connection refused")) + + err = rp.Stop(ctx) + require.NoError(t.T(), err) +} + +/*func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() + + relayminerZoneServiceName := "fakehostservice" + relayminerZoneServiceAddr := "fakehostservice.com:8648" + relayminerIPV6ServiceName := "ipv6service" + + supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ + relayminerZoneServiceName: { + { + Url: "http://fakehostservice.com:8648", + RpcType: sharedtypes.RPCType_JSON_RPC, + }, + }, + relayminerIPV6ServiceName: { + { + Url: "http://ipv6service:8649", + RpcType: sharedtypes.RPCType_JSON_RPC, + }, + }, + } + + servicesConfigMap := map[string]*config.RelayMinerServerConfig{ + relayminerZoneServiceAddr: &config.RelayMinerServerConfig{ + ListenAddress: relayminerZoneServiceAddr, + ServerType: config.RelayMinerServerTypeHTTP, + SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ + relayminerZoneServiceName: &config.RelayMinerSupplierConfig{ + ServerType: config.RelayMinerServerTypeHTTP, + ServiceId: relayminerZoneServiceName, + ServiceConfig: &config.RelayMinerSupplierServiceConfig{ + BackendUrl: &url.URL{ + Scheme: "http", + Host: "fakehostservice.com:8648", + Path: "/", + }, + }, + PubliclyExposedEndpoints: []string{ + "fakehostservice.com", + }, + }, + relayminerIPV6ServiceName: &config.RelayMinerSupplierConfig{ + ServerType: config.RelayMinerServerTypeHTTP, + ServiceId: relayminerIPV6ServiceName, + ServiceConfig: &config.RelayMinerSupplierServiceConfig{ + BackendUrl: &url.URL{ + Scheme: "http", + Host: "[::1]:8649", + Path: "/", + }, + }, + PubliclyExposedEndpoints: []string{ + "ipv6service", + }, + }, + }, + }, + } + + relayProxyBehavior := append(t.relayerProxyBehavior, []func(*testproxy.TestBehavior){ + testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), + testproxy.WithServicesConfigMap(servicesConfigMap), + }...) + + test := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), relayProxyBehavior...) + + // copying services config maps from default values + for k, v := range t.servicesConfigMap { + servicesConfigMap[k] = v + } + + rp, err := proxy.NewRelayerProxy( + test.Deps, + proxy.WithSigningKeyNames([]string{t.supplierOperatorPingAllKeyName}), + proxy.WithServicesConfigMap(servicesConfigMap), + ) + require.NoError(t.T(), err) + + go func() { + err := rp.Start(ctx) + if err != http.ErrServerClosed { + require.NoError(t.T(), err) + } + }() + + err = rp.PingAll(ctx) + require.NoError(t.T(), err) + + err = rp.Stop(ctx) + require.NoError(t.T(), err) + }*/ + func sendRequestWithUnparsableBody( t *testing.T, test *testproxy.TestBehavior, diff --git a/testutil/testproxy/relayerproxy.go b/testutil/testproxy/relayerproxy.go index e3d0981a6..0d425ab2e 100644 --- a/testutil/testproxy/relayerproxy.go +++ b/testutil/testproxy/relayerproxy.go @@ -12,6 +12,7 @@ import ( "net/url" "os" "testing" + "time" "cosmossdk.io/depinject" ring_secp256k1 "github.com/athanorlabs/go-dleq/secp256k1" @@ -20,14 +21,17 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/types/bech32" + "github.com/golang/mock/gomock" "github.com/pokt-network/ring-go" sdktypes "github.com/pokt-network/shannon-sdk/types" "github.com/stretchr/testify/require" "github.com/pokt-network/poktroll/pkg/observable/channel" "github.com/pokt-network/poktroll/pkg/polylog" + "github.com/pokt-network/poktroll/pkg/relayer" "github.com/pokt-network/poktroll/pkg/relayer/config" "github.com/pokt-network/poktroll/pkg/signer" + "github.com/pokt-network/poktroll/testutil/mockrelayer" testsession "github.com/pokt-network/poktroll/testutil/session" "github.com/pokt-network/poktroll/testutil/testclient/testblock" "github.com/pokt-network/poktroll/testutil/testclient/testdelegation" @@ -97,6 +101,19 @@ func NewRelayerProxyTestBehavior( return test } +// ShutdownServiceID gracefully shuts down the http server for a given service id. +func (t *TestBehavior) ShutdownServiceID(serviceID string) error { + srv, ok := t.proxyServersMap[serviceID] + if !ok { + return fmt.Errorf("shutdown service id: not found") + } + + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + return srv.Shutdown(ctx) +} + // WithRelayerProxyDependenciesForBlockHeight creates the dependencies for the relayer proxy // from the TestBehavior.mocks so they have the right interface and can be // used by the dependency injection framework. @@ -139,6 +156,14 @@ func WithRelayerProxyDependenciesForBlockHeight( } } +// WithRelayMeter creates the dependencies mocks for the relayproxy to use a relay meter. +func WithRelayMeter() func(*TestBehavior) { + return func(test *TestBehavior) { + relayMeter := newMockRelayMeter(test.t) + test.Deps = depinject.Configs(test.Deps, depinject.Supply(relayMeter)) + } +} + // WithServicesConfigMap creates the services that the relayer proxy will // proxy requests to. // It creates an HTTP server for each service and starts listening on the @@ -277,6 +302,15 @@ func WithSuccessiveSessions( } } +func newMockRelayMeter(t *testing.T) relayer.RelayMeter { + ctrl := gomock.NewController(t) + + relayMeter := mockrelayer.NewMockRelayMeter(ctrl) + relayMeter.EXPECT().Start(gomock.Any()).Return(nil).AnyTimes() + + return relayMeter +} + // MarshalAndSend marshals the request and sends it to the provided service. func MarshalAndSend( test *TestBehavior, From fe6342ab20594a0294851dc52d8267ce13937c26 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 20 Jan 2025 02:22:09 +0100 Subject: [PATCH 35/55] add proxy different endpoints ping tests --- go.mod | 2 ++ go.sum | 35 +++++++++++++++++++++++++++++ pkg/relayer/proxy/proxy_test.go | 39 ++++++++++++++++++++++++++------- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 162807307..8e32e4018 100644 --- a/go.mod +++ b/go.mod @@ -80,6 +80,7 @@ require ( require ( cosmossdk.io/x/tx v0.13.4 + github.com/foxcpp/go-mockdns v1.1.0 github.com/jhump/protoreflect v1.16.0 github.com/mitchellh/mapstructure v1.5.0 ) @@ -223,6 +224,7 @@ require ( github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/miekg/dns v1.1.57 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect diff --git a/go.sum b/go.sum index 761f5909e..7edca2823 100644 --- a/go.sum +++ b/go.sum @@ -498,6 +498,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI= +github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -889,6 +891,8 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -1235,6 +1239,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1276,6 +1283,9 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1337,6 +1347,11 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1380,6 +1395,10 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1479,13 +1498,22 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1498,6 +1526,10 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1569,6 +1601,9 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/relayer/proxy/proxy_test.go b/pkg/relayer/proxy/proxy_test.go index f260894bd..1740d525a 100644 --- a/pkg/relayer/proxy/proxy_test.go +++ b/pkg/relayer/proxy/proxy_test.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "io" + "net" "net/http" "net/url" "strings" @@ -12,6 +13,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/foxcpp/go-mockdns" sdktypes "github.com/pokt-network/shannon-sdk/types" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -652,7 +654,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { ctx, cancel := context.WithCancel(context.TODO()) defer cancel() - secondServiceName := "secondService" + secondServiceName := "secondservice" secondServiceAddr := "127.0.0.1:8246" // adding supplier endpoint. @@ -870,18 +872,31 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() require.NoError(t.T(), err) } -/*func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { +func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { ctx, cancel := context.WithCancel(context.TODO()) defer cancel() - relayminerZoneServiceName := "fakehostservice" - relayminerZoneServiceAddr := "fakehostservice.com:8648" + srv, err := mockdns.NewServer(map[string]mockdns.Zone{ + "exampleservice.org.": { + A: []string{"127.0.0.1"}, + }, + }, false) + require.NoError(t.T(), err) + defer srv.Close() + + srv.PatchNet(net.DefaultResolver) + defer mockdns.UnpatchNet(net.DefaultResolver) + + relayminerZoneServiceName := "exampleservice.org" + relayminerZoneServiceAddr := "exampleservice.org:8249" + relayminerIPV6ServiceName := "ipv6service" + relayminerIPV6ServiceAddr := "localhost:8250" supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ relayminerZoneServiceName: { { - Url: "http://fakehostservice.com:8648", + Url: "http://exampleservice.org:8648", RpcType: sharedtypes.RPCType_JSON_RPC, }, }, @@ -904,14 +919,20 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() ServiceConfig: &config.RelayMinerSupplierServiceConfig{ BackendUrl: &url.URL{ Scheme: "http", - Host: "fakehostservice.com:8648", + Host: "exampleservice.org:8648", Path: "/", }, }, PubliclyExposedEndpoints: []string{ - "fakehostservice.com", + "exampleservice.org", }, }, + }, + }, + relayminerIPV6ServiceAddr: &config.RelayMinerServerConfig{ + ListenAddress: relayminerIPV6ServiceAddr, + ServerType: config.RelayMinerServerTypeHTTP, + SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ relayminerIPV6ServiceName: &config.RelayMinerSupplierConfig{ ServerType: config.RelayMinerServerTypeHTTP, ServiceId: relayminerIPV6ServiceName, @@ -956,12 +977,14 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() } }() + time.Sleep(time.Millisecond) + err = rp.PingAll(ctx) require.NoError(t.T(), err) err = rp.Stop(ctx) require.NoError(t.T(), err) - }*/ +} func sendRequestWithUnparsableBody( t *testing.T, From d7abf605980bcc191379eb693b382f398dec9ac9 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 20 Jan 2025 13:18:25 +0100 Subject: [PATCH 36/55] stabilize flaky helpers in testproxy --- pkg/relayer/proxy/proxy_test.go | 29 ++++++++++++++++++----------- testutil/testproxy/relayerproxy.go | 15 ++++++++++----- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/pkg/relayer/proxy/proxy_test.go b/pkg/relayer/proxy/proxy_test.go index 1740d525a..1e2a0fc13 100644 --- a/pkg/relayer/proxy/proxy_test.go +++ b/pkg/relayer/proxy/proxy_test.go @@ -577,7 +577,6 @@ func (t *RelayProxyPingAllSuite) SetupSuite() { appPrivateKey := secp256k1.GenPrivKey() t.defaultRelayMinerServerAddress = "127.0.0.1:8245" t.defaultServiceName = "defaultService" - t.supplierEndpoints = map[string][]*sharedtypes.SupplierEndpoint{ t.defaultServiceName: { { @@ -641,7 +640,9 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithSingleRelayServer() { }() - time.Sleep(time.Millisecond) + // waiting for relayer proxy to start + // and perform ping request. + time.Sleep(100 * time.Millisecond) err = rp.PingAll(ctx) require.NoError(t.T(), err) @@ -716,7 +717,9 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { } }() - time.Sleep(time.Millisecond) + // waiting for relayer proxy to start + // and perform ping request. + time.Sleep(100 * time.Millisecond) err = rp.PingAll(ctx) require.NoError(t.T(), err) @@ -804,7 +807,7 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ failingServiceName: { { - Url: "http://failingservice:8647", + Url: "http://failingservice:8648", RpcType: sharedtypes.RPCType_JSON_RPC, }, }, @@ -821,7 +824,7 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() ServiceConfig: &config.RelayMinerSupplierServiceConfig{ BackendUrl: &url.URL{ Scheme: "http", - Host: "127.0.0.1:8647", + Host: "127.0.0.1:8648", Path: "/", }, }, @@ -859,7 +862,9 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() } }() - time.Sleep(time.Millisecond) + // waiting for relayer proxy to start + // and perform ping request. + time.Sleep(100 * time.Millisecond) err = test.ShutdownServiceID(failingServiceName) require.NoError(t.T(), err) @@ -896,13 +901,13 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ relayminerZoneServiceName: { { - Url: "http://exampleservice.org:8648", + Url: "http://exampleservice.org:8649", RpcType: sharedtypes.RPCType_JSON_RPC, }, }, relayminerIPV6ServiceName: { { - Url: "http://ipv6service:8649", + Url: "http://ipv6service:8650", RpcType: sharedtypes.RPCType_JSON_RPC, }, }, @@ -919,7 +924,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { ServiceConfig: &config.RelayMinerSupplierServiceConfig{ BackendUrl: &url.URL{ Scheme: "http", - Host: "exampleservice.org:8648", + Host: "exampleservice.org:8649", Path: "/", }, }, @@ -939,7 +944,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { ServiceConfig: &config.RelayMinerSupplierServiceConfig{ BackendUrl: &url.URL{ Scheme: "http", - Host: "[::1]:8649", + Host: "[::1]:8650", Path: "/", }, }, @@ -977,7 +982,9 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { } }() - time.Sleep(time.Millisecond) + // waiting for relayer proxy to start + // and perform ping request. + time.Sleep(100 * time.Millisecond) err = rp.PingAll(ctx) require.NoError(t.T(), err) diff --git a/testutil/testproxy/relayerproxy.go b/testutil/testproxy/relayerproxy.go index 0d425ab2e..f111c5309 100644 --- a/testutil/testproxy/relayerproxy.go +++ b/testutil/testproxy/relayerproxy.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "io" + "net" "net/http" "net/url" "os" @@ -183,13 +184,17 @@ $ go test -v -count=1 -run TestRelayerProxy ./pkg/relayer/...`) } for _, serviceConfig := range servicesConfigMap { for serviceId, supplierConfig := range serviceConfig.SupplierConfigsMap { - server := &http.Server{Addr: supplierConfig.ServiceConfig.BackendUrl.Host} - server.Handler = http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - sendJSONRPCResponse(test.t, w) - }) + listener, err := net.Listen("tcp", supplierConfig.ServiceConfig.BackendUrl.Host) + require.NoError(test.t, err) + + server := &http.Server{ + Handler: http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + sendJSONRPCResponse(test.t, w) + }), + } go func() { - err := server.ListenAndServe() + err := server.Serve(listener) if err != nil && !errors.Is(err, http.ErrServerClosed) { require.NoError(test.t, err) } From e35986e753359f6d1324db051788fd0b27b5cdd4 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Tue, 21 Jan 2025 02:14:40 +0100 Subject: [PATCH 37/55] add comments and refactor variable names --- pkg/relayer/proxy/proxy_test.go | 98 ++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/pkg/relayer/proxy/proxy_test.go b/pkg/relayer/proxy/proxy_test.go index 1e2a0fc13..b88ddc399 100644 --- a/pkg/relayer/proxy/proxy_test.go +++ b/pkg/relayer/proxy/proxy_test.go @@ -557,28 +557,30 @@ func TestRelayerProxy_Relays(t *testing.T) { } } +// RelayProxyPingAllSuite implements the suite to test the relay proxy ping +// application logic. type RelayProxyPingAllSuite struct { suite.Suite relayerProxyBehavior []func(*testproxy.TestBehavior) servicesConfigMap map[string]*config.RelayMinerServerConfig - supplierEndpoints map[string][]*sharedtypes.SupplierEndpoint supplierOperatorPingAllKeyName string - defaultRelayMinerServerAddress string - defaultServiceName string } +// TestRelayProxyPingAllSuite executes the RelayProxyPingAllSuite test suite. func TestRelayProxyPingAllSuite(t *testing.T) { suite.Run(t, new(RelayProxyPingAllSuite)) } -// SetupSuite setups a single default relayminer with one supplier. +// SetupSuite setups a single default relayminer with one supplier. The +// default relayminer will be reused in every subsequent tests in the +// suite. func (t *RelayProxyPingAllSuite) SetupSuite() { t.supplierOperatorPingAllKeyName = "supplierPingAllKeyName" appPrivateKey := secp256k1.GenPrivKey() - t.defaultRelayMinerServerAddress = "127.0.0.1:8245" - t.defaultServiceName = "defaultService" - t.supplierEndpoints = map[string][]*sharedtypes.SupplierEndpoint{ - t.defaultServiceName: { + defaultRelayMinerServerAddress := "127.0.0.1:8245" + defaultServiceName := "defaultService" + supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ + defaultServiceName: { { Url: "http://supplier1pingall:8645", RpcType: sharedtypes.RPCType_JSON_RPC, @@ -587,12 +589,12 @@ func (t *RelayProxyPingAllSuite) SetupSuite() { } t.servicesConfigMap = map[string]*config.RelayMinerServerConfig{ - t.defaultRelayMinerServerAddress: { + defaultRelayMinerServerAddress: { ServerType: config.RelayMinerServerTypeHTTP, - ListenAddress: t.defaultRelayMinerServerAddress, + ListenAddress: defaultRelayMinerServerAddress, SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ - t.defaultServiceName: { - ServiceId: t.defaultServiceName, + defaultServiceName: { + ServiceId: defaultServiceName, ServerType: config.RelayMinerServerTypeHTTP, ServiceConfig: &config.RelayMinerSupplierServiceConfig{ BackendUrl: &url.URL{ @@ -612,13 +614,15 @@ func (t *RelayProxyPingAllSuite) SetupSuite() { t.relayerProxyBehavior = []func(*testproxy.TestBehavior){ testproxy.WithRelayerProxyDependenciesForBlockHeight(t.supplierOperatorPingAllKeyName, 1), testproxy.WithServicesConfigMap(t.servicesConfigMap), - testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, t.supplierEndpoints), + testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), testproxy.WithDefaultApplication(appPrivateKey), - testproxy.WithDefaultSessionSupplier(t.supplierOperatorPingAllKeyName, t.defaultServiceName, appPrivateKey), + testproxy.WithDefaultSessionSupplier(t.supplierOperatorPingAllKeyName, defaultServiceName, appPrivateKey), testproxy.WithRelayMeter(), } } +// TestOKPingAllWithSingleRelayServer reuses the default relayminer with one +// supplier to test the relayproxy.PingAll method. func (t *RelayProxyPingAllSuite) TestOKPingAllWithSingleRelayServer() { ctx, cancel := context.WithCancel(context.TODO()) defer cancel() @@ -637,7 +641,6 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithSingleRelayServer() { if http.ErrServerClosed != err { require.NoError(t.T(), err) } - }() // waiting for relayer proxy to start @@ -651,12 +654,14 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithSingleRelayServer() { require.NoError(t.T(), err) } +// TestOKPingAllWithMultipleRelayServers reuses default relayminer and +// instantiates an additional one to test the connectivity. func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { ctx, cancel := context.WithCancel(context.TODO()) defer cancel() + secondRelayMinerAddr := "127.0.0.1:8246" secondServiceName := "secondservice" - secondServiceAddr := "127.0.0.1:8246" // adding supplier endpoint. supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ @@ -669,9 +674,9 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { } servicesConfigMap := map[string]*config.RelayMinerServerConfig{ - secondServiceAddr: { + secondRelayMinerAddr: { ServerType: config.RelayMinerServerTypeHTTP, - ListenAddress: secondServiceAddr, + ListenAddress: secondRelayMinerAddr, SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ secondServiceName: { ServiceId: secondServiceName, @@ -698,7 +703,8 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { testBehavoirs := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), relayProxyBehavior...) - // copying default service config map + // copying the default relayminer in the test service config + // map for the relay proxy. for k, v := range t.servicesConfigMap { servicesConfigMap[k] = v } @@ -728,12 +734,14 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { require.NoError(t.T(), err) } +// TestNOKPingAllWithPartialFailureAtStartup test the connectivity for multiple +// relayminer with a partial sucess/failure at startup. func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAtStartup() { ctx, cancel := context.WithCancel(context.TODO()) defer cancel() + failingRelayMinerAddr := "127.0.0.1:8247" failingServiceName := "failingservice" - failingServiceAddr := "127.0.0.1:8247" supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ failingServiceName: { @@ -745,8 +753,8 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAtStartup() { } servicesConfigMap := map[string]*config.RelayMinerServerConfig{ - failingServiceAddr: &config.RelayMinerServerConfig{ - ListenAddress: failingServiceAddr, + failingRelayMinerAddr: &config.RelayMinerServerConfig{ + ListenAddress: failingRelayMinerAddr, ServerType: config.RelayMinerServerTypeHTTP, SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ failingServiceName: &config.RelayMinerSupplierConfig{ @@ -774,7 +782,8 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAtStartup() { test := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), relayProxyBehavior...) - // copying services config maps from default values + // copying the default relayminer in the test service config + // map for the relay proxy. for k, v := range t.servicesConfigMap { servicesConfigMap[k] = v } @@ -786,9 +795,12 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAtStartup() { ) require.NoError(t.T(), err) + // we are explicitly shutting down a supplier to simulate a + // failure while testing the connectivity at startup. err = test.ShutdownServiceID(failingServiceName) require.NoError(t.T(), err) + // testing connectivity at startup err = rp.Start(ctx) require.Error(t.T(), err) require.True(t.T(), strings.Contains(err.Error(), "connection refused")) @@ -797,12 +809,14 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAtStartup() { require.NoError(t.T(), err) } +// TestNOKPingAllWithPartialFailureAfterStartup test the connectivity for multiple +// relayminer with a partial sucess/failure at runtime. func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() { ctx, cancel := context.WithCancel(context.TODO()) defer cancel() + failingRelayMinerAddr := "127.0.0.1:8248" failingServiceName := "faillingservice" - failingServiceAddr := "127.0.0.1:8248" supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ failingServiceName: { @@ -814,8 +828,8 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() } servicesConfigMap := map[string]*config.RelayMinerServerConfig{ - failingServiceAddr: &config.RelayMinerServerConfig{ - ListenAddress: failingServiceAddr, + failingRelayMinerAddr: &config.RelayMinerServerConfig{ + ListenAddress: failingRelayMinerAddr, ServerType: config.RelayMinerServerTypeHTTP, SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ failingServiceName: &config.RelayMinerSupplierConfig{ @@ -843,7 +857,8 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() test := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), relayProxyBehavior...) - // copying services config maps from default values + // copying the default relayminer in the test service config + // map for the relay proxy. for k, v := range t.servicesConfigMap { servicesConfigMap[k] = v } @@ -866,6 +881,8 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() // and perform ping request. time.Sleep(100 * time.Millisecond) + // we are explicitly shutting down a supplier to simulate an error + // while testing the connectivity. err = test.ShutdownServiceID(failingServiceName) require.NoError(t.T(), err) @@ -877,6 +894,8 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() require.NoError(t.T(), err) } +// TestOKPingAllDifferentEndpoint test the connectivity with different type of +// endpoints (ipv6, domain name). func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { ctx, cancel := context.WithCancel(context.TODO()) defer cancel() @@ -892,20 +911,20 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { srv.PatchNet(net.DefaultResolver) defer mockdns.UnpatchNet(net.DefaultResolver) - relayminerZoneServiceName := "exampleservice.org" - relayminerZoneServiceAddr := "exampleservice.org:8249" + relayminerDomainNameAddr := "exampleservice.org:8249" + domainNameServiceName := "exampleservice.org" - relayminerIPV6ServiceName := "ipv6service" relayminerIPV6ServiceAddr := "localhost:8250" + IPV6ServiceName := "ipv6service" supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ - relayminerZoneServiceName: { + domainNameServiceName: { { Url: "http://exampleservice.org:8649", RpcType: sharedtypes.RPCType_JSON_RPC, }, }, - relayminerIPV6ServiceName: { + IPV6ServiceName: { { Url: "http://ipv6service:8650", RpcType: sharedtypes.RPCType_JSON_RPC, @@ -914,13 +933,13 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { } servicesConfigMap := map[string]*config.RelayMinerServerConfig{ - relayminerZoneServiceAddr: &config.RelayMinerServerConfig{ - ListenAddress: relayminerZoneServiceAddr, + relayminerDomainNameAddr: &config.RelayMinerServerConfig{ + ListenAddress: relayminerDomainNameAddr, ServerType: config.RelayMinerServerTypeHTTP, SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ - relayminerZoneServiceName: &config.RelayMinerSupplierConfig{ + domainNameServiceName: &config.RelayMinerSupplierConfig{ ServerType: config.RelayMinerServerTypeHTTP, - ServiceId: relayminerZoneServiceName, + ServiceId: domainNameServiceName, ServiceConfig: &config.RelayMinerSupplierServiceConfig{ BackendUrl: &url.URL{ Scheme: "http", @@ -938,9 +957,9 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { ListenAddress: relayminerIPV6ServiceAddr, ServerType: config.RelayMinerServerTypeHTTP, SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ - relayminerIPV6ServiceName: &config.RelayMinerSupplierConfig{ + IPV6ServiceName: &config.RelayMinerSupplierConfig{ ServerType: config.RelayMinerServerTypeHTTP, - ServiceId: relayminerIPV6ServiceName, + ServiceId: IPV6ServiceName, ServiceConfig: &config.RelayMinerSupplierServiceConfig{ BackendUrl: &url.URL{ Scheme: "http", @@ -963,7 +982,8 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { test := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), relayProxyBehavior...) - // copying services config maps from default values + // copying the default relayminer in the test service config + // map for the relay proxy. for k, v := range t.servicesConfigMap { servicesConfigMap[k] = v } From dd6b7e8acba12b471493e59abd81d0c68c9c5b81 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 27 Jan 2025 14:07:27 +0100 Subject: [PATCH 38/55] fix typo in Tiltfile --- Tiltfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tiltfile b/Tiltfile index 9e4d9f0be..1e05fe885 100644 --- a/Tiltfile +++ b/Tiltfile @@ -325,7 +325,7 @@ for x in range(localnet_config["relayminers"]["count"]): # Use with pprof like this: `go tool pprof -http=:3333 http://localhost:6070/debug/pprof/goroutine` str(6069 + actor_number) + ":6060", # Relayminer pprof port. relayminer1 - exposes 6070, relayminer2 exposes 6071, etc. - str(7000 + actor_number) + ":8081", # Relayminer ping port. relayminer1 - exposes 7001, relayminer2 exposes 7002, ect. + str(7000 + actor_number) + ":8081", # Relayminer ping port. relayminer1 - exposes 7001, relayminer2 exposes 7002, etc. ], ) From ad39a0c9cb98223a6bab6110f4b5c8c238234886 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 27 Jan 2025 14:35:55 +0100 Subject: [PATCH 39/55] fix tyop --- pkg/relayer/proxy/proxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/relayer/proxy/proxy.go b/pkg/relayer/proxy/proxy.go index 5751e2746..8a6ad09cc 100644 --- a/pkg/relayer/proxy/proxy.go +++ b/pkg/relayer/proxy/proxy.go @@ -227,7 +227,7 @@ func (rp *relayerProxy) PingAll(ctx context.Context) error { if err != nil { rp.logger.Error().Err(err). - Msg("an unexpected error occured while pinging backend URL") + Msg("an unexpected error occured while pinging backend URL(s)") return err } From 7f21be9975aec8e5b471b1dd9210dbe77b03ca40 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 27 Jan 2025 14:41:17 +0100 Subject: [PATCH 40/55] categorized as errors any HTTP status code higher or equal to 400 --- pkg/relayer/proxy/synchronous.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/relayer/proxy/synchronous.go b/pkg/relayer/proxy/synchronous.go index f971cdb5a..c60d2aa45 100644 --- a/pkg/relayer/proxy/synchronous.go +++ b/pkg/relayer/proxy/synchronous.go @@ -109,7 +109,8 @@ func (sync *synchronousRPCServer) Ping(ctx context.Context) error { } _ = resp.Body.Close() - if resp.StatusCode >= http.StatusInternalServerError { + // DEV_NOTE: Return ANY HTTP error. + if resp.StatusCode >= http.StatusBadRequest { return ErrRelayerProxySupplierNotReachable.Wrapf( "endpoint URL %q err: %s", supplierCfg.ServiceConfig.BackendUrl.String(), err) From 446d2f2c747cd8f651f4df99d9e2405ecfdf9e5b Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 27 Jan 2025 14:45:08 +0100 Subject: [PATCH 41/55] improve error handling while serving http request for ping server --- pkg/relayer/relayminer.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index 45e997f76..25c510bb8 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -2,6 +2,7 @@ package relayer import ( "context" + "errors" "net" "net/http" "net/http/pprof" @@ -148,8 +149,8 @@ func (rel *relayMiner) ServePing(ctx context.Context, network, addr string) erro // ping requests. A single ping request on the relay server broadcasts a // ping to all backing services/data nodes. go func() { - if err := http.Serve(ln, rel.newPinghandlerFn(ctx, ln)); err != nil { - rel.logger.Error().Err(err).Msg("unable to serve ping server") + if err := http.Serve(ln, rel.newPinghandlerFn(ctx, ln)); err != nil && !errors.Is(http.ErrServerClosed, err) { + rel.logger.Error().Err(err).Msg("ping server unexpectedly closed") } }() From d2ade64ff09d3530b627ec4425917549be39e0af Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 27 Jan 2025 15:10:31 +0100 Subject: [PATCH 42/55] distinguish 502 from 503 errors in ping handler for error handling --- pkg/relayer/relayminer.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index 25c510bb8..fdce69333 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -6,6 +6,7 @@ import ( "net" "net/http" "net/http/pprof" + "net/url" "cosmossdk.io/depinject" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -168,7 +169,12 @@ func (rel *relayMiner) newPinghandlerFn(ctx context.Context, ln net.Listener) ht rel.logger.Debug().Msg("pinging relay servers...") if err := rel.relayerProxy.PingAll(ctx); err != nil { - w.WriteHeader(http.StatusBadGateway) + var urlError url.Error + if errors.As(err, &urlError) && urlError.Temporary() { + w.WriteHeader(http.StatusGatewayTimeout) + } else { + w.WriteHeader(http.StatusBadGateway) + } return } From 53ca20e134724255638e6d2442a216237b516830 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 27 Jan 2025 15:22:57 +0100 Subject: [PATCH 43/55] rely on testing temp dir for testing files --- pkg/relayer/relayminer_test.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index 286bc6260..0186fb270 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -4,7 +4,7 @@ import ( "context" "net" "net/http" - "os" + "path/filepath" "testing" "time" @@ -102,16 +102,15 @@ func TestRelayMiner_Ping(t *testing.T) { time.Sleep(time.Millisecond) - filename := "/tmp/relayerminer.ping.sock" + relayminerSocketPath := filepath.Join(t.TempDir(), "relayerminer.ping.sock") - relayminer.ServePing(ctx, "unix", filename) - defer os.Remove(filename) + relayminer.ServePing(ctx, "unix", relayminerSocketPath) time.Sleep(time.Millisecond) transport := &http.Transport{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - return net.Dial("unix", "/tmp/relayerminer.ping.sock") + return net.Dial("unix", relayminerSocketPath) }, } From 39d1458e5bad7dfed1f7ac493969890ab73da3c3 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 27 Jan 2025 15:42:41 +0100 Subject: [PATCH 44/55] improve relayminer configuration documentation --- docusaurus/docs/operate/configs/relayminer_config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/operate/configs/relayminer_config.md b/docusaurus/docs/operate/configs/relayminer_config.md index 5c68bc705..a7ac2a4ae 100644 --- a/docusaurus/docs/operate/configs/relayminer_config.md +++ b/docusaurus/docs/operate/configs/relayminer_config.md @@ -179,7 +179,7 @@ You can learn how to use that endpoint on the [Performance Troubleshooting](../. Configures a `ping` server to test the connectivity of all backend URLs. If all the backend URLs are reachable, the endpoint returns a 204 HTTP Code. If one or more backend URLs aren't reachable, the service -returns an 500 HTTP Internal server error. +returns an appropriate HTTP error. Example configuration: From 07361b99980032de6d702141e3c0d7c30f0cf1f4 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Tue, 28 Jan 2025 05:24:17 +0100 Subject: [PATCH 45/55] improve error message for ping request --- pkg/relayer/proxy/synchronous.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/relayer/proxy/synchronous.go b/pkg/relayer/proxy/synchronous.go index c60d2aa45..cb9614742 100644 --- a/pkg/relayer/proxy/synchronous.go +++ b/pkg/relayer/proxy/synchronous.go @@ -112,8 +112,8 @@ func (sync *synchronousRPCServer) Ping(ctx context.Context) error { // DEV_NOTE: Return ANY HTTP error. if resp.StatusCode >= http.StatusBadRequest { return ErrRelayerProxySupplierNotReachable.Wrapf( - "endpoint URL %q err: %s", - supplierCfg.ServiceConfig.BackendUrl.String(), err) + "endpoint URL %q; status code: %d", + supplierCfg.ServiceConfig.BackendUrl.String(), err, resp.StatusCode) } } From 0c11e0217714ed9a91fd27aacedbd9a282bd7c7d Mon Sep 17 00:00:00 2001 From: eddyzags Date: Tue, 28 Jan 2025 05:24:35 +0100 Subject: [PATCH 46/55] minor fix --- pkg/relayer/relayminer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index fdce69333..645cebe19 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -169,7 +169,7 @@ func (rel *relayMiner) newPinghandlerFn(ctx context.Context, ln net.Listener) ht rel.logger.Debug().Msg("pinging relay servers...") if err := rel.relayerProxy.PingAll(ctx); err != nil { - var urlError url.Error + var urlError *url.Error if errors.As(err, &urlError) && urlError.Temporary() { w.WriteHeader(http.StatusGatewayTimeout) } else { From 898833562e3bfaa259a3b5eb11f35bedafc885f9 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 2 Feb 2025 11:33:05 +0100 Subject: [PATCH 47/55] add comments to explain WithServiceConfigMap() function management to avoid flaky tests --- testutil/testproxy/relayerproxy.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/testutil/testproxy/relayerproxy.go b/testutil/testproxy/relayerproxy.go index f111c5309..92003d491 100644 --- a/testutil/testproxy/relayerproxy.go +++ b/testutil/testproxy/relayerproxy.go @@ -166,9 +166,12 @@ func WithRelayMeter() func(*TestBehavior) { } // WithServicesConfigMap creates the services that the relayer proxy will -// proxy requests to. -// It creates an HTTP server for each service and starts listening on the -// provided host. +// proxy requests to. It creates an HTTP server for each service and starts +// listening on the provided host. +// +// It is recommended to run this function on the main Go routine to ensure that +// the HTTP servers created for each service are fully initialized and ready to +// receive requests before executing the test cases. func WithServicesConfigMap( servicesConfigMap map[string]*config.RelayMinerServerConfig, ) func(*TestBehavior) { From 2947c2b48b50fb158c92f2b19a5f7accdf2321f6 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 2 Feb 2025 11:44:02 +0100 Subject: [PATCH 48/55] rely on defaultService pkg level constant for ping test suite --- pkg/relayer/proxy/proxy_test.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pkg/relayer/proxy/proxy_test.go b/pkg/relayer/proxy/proxy_test.go index b88ddc399..4c0dd7a09 100644 --- a/pkg/relayer/proxy/proxy_test.go +++ b/pkg/relayer/proxy/proxy_test.go @@ -578,9 +578,8 @@ func (t *RelayProxyPingAllSuite) SetupSuite() { t.supplierOperatorPingAllKeyName = "supplierPingAllKeyName" appPrivateKey := secp256k1.GenPrivKey() defaultRelayMinerServerAddress := "127.0.0.1:8245" - defaultServiceName := "defaultService" supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ - defaultServiceName: { + defaultService: { { Url: "http://supplier1pingall:8645", RpcType: sharedtypes.RPCType_JSON_RPC, @@ -593,8 +592,8 @@ func (t *RelayProxyPingAllSuite) SetupSuite() { ServerType: config.RelayMinerServerTypeHTTP, ListenAddress: defaultRelayMinerServerAddress, SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ - defaultServiceName: { - ServiceId: defaultServiceName, + defaultService: { + ServiceId: defaultService, ServerType: config.RelayMinerServerTypeHTTP, ServiceConfig: &config.RelayMinerSupplierServiceConfig{ BackendUrl: &url.URL{ @@ -616,7 +615,7 @@ func (t *RelayProxyPingAllSuite) SetupSuite() { testproxy.WithServicesConfigMap(t.servicesConfigMap), testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), testproxy.WithDefaultApplication(appPrivateKey), - testproxy.WithDefaultSessionSupplier(t.supplierOperatorPingAllKeyName, defaultServiceName, appPrivateKey), + testproxy.WithDefaultSessionSupplier(t.supplierOperatorPingAllKeyName, defaultService, appPrivateKey), testproxy.WithRelayMeter(), } } From baa9b610475fcd139a51bfcc9e79588c97e987b5 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 2 Feb 2025 11:44:23 +0100 Subject: [PATCH 49/55] remove unused variable in synchrounous Ping method --- pkg/relayer/proxy/synchronous.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/relayer/proxy/synchronous.go b/pkg/relayer/proxy/synchronous.go index cb9614742..2b1cf652d 100644 --- a/pkg/relayer/proxy/synchronous.go +++ b/pkg/relayer/proxy/synchronous.go @@ -113,7 +113,7 @@ func (sync *synchronousRPCServer) Ping(ctx context.Context) error { if resp.StatusCode >= http.StatusBadRequest { return ErrRelayerProxySupplierNotReachable.Wrapf( "endpoint URL %q; status code: %d", - supplierCfg.ServiceConfig.BackendUrl.String(), err, resp.StatusCode) + supplierCfg.ServiceConfig.BackendUrl.String(), resp.StatusCode) } } From 3800411614713c34001550dba38d7cd2f8d97740 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 2 Feb 2025 11:48:33 +0100 Subject: [PATCH 50/55] re-using supplierOperatorKeyName package level constant variable for ping test suite --- pkg/relayer/proxy/proxy_test.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/pkg/relayer/proxy/proxy_test.go b/pkg/relayer/proxy/proxy_test.go index 4c0dd7a09..2470578c1 100644 --- a/pkg/relayer/proxy/proxy_test.go +++ b/pkg/relayer/proxy/proxy_test.go @@ -561,9 +561,8 @@ func TestRelayerProxy_Relays(t *testing.T) { // application logic. type RelayProxyPingAllSuite struct { suite.Suite - relayerProxyBehavior []func(*testproxy.TestBehavior) - servicesConfigMap map[string]*config.RelayMinerServerConfig - supplierOperatorPingAllKeyName string + relayerProxyBehavior []func(*testproxy.TestBehavior) + servicesConfigMap map[string]*config.RelayMinerServerConfig } // TestRelayProxyPingAllSuite executes the RelayProxyPingAllSuite test suite. @@ -575,7 +574,6 @@ func TestRelayProxyPingAllSuite(t *testing.T) { // default relayminer will be reused in every subsequent tests in the // suite. func (t *RelayProxyPingAllSuite) SetupSuite() { - t.supplierOperatorPingAllKeyName = "supplierPingAllKeyName" appPrivateKey := secp256k1.GenPrivKey() defaultRelayMinerServerAddress := "127.0.0.1:8245" supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ @@ -611,11 +609,11 @@ func (t *RelayProxyPingAllSuite) SetupSuite() { } t.relayerProxyBehavior = []func(*testproxy.TestBehavior){ - testproxy.WithRelayerProxyDependenciesForBlockHeight(t.supplierOperatorPingAllKeyName, 1), + testproxy.WithRelayerProxyDependenciesForBlockHeight(supplierOperatorKeyName, 1), testproxy.WithServicesConfigMap(t.servicesConfigMap), - testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), + testproxy.WithDefaultSupplier(supplierOperatorKeyName, supplierEndpoints), testproxy.WithDefaultApplication(appPrivateKey), - testproxy.WithDefaultSessionSupplier(t.supplierOperatorPingAllKeyName, defaultService, appPrivateKey), + testproxy.WithDefaultSessionSupplier(supplierOperatorKeyName, defaultService, appPrivateKey), testproxy.WithRelayMeter(), } } @@ -630,7 +628,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithSingleRelayServer() { rp, err := proxy.NewRelayerProxy( testBehavoirs.Deps, - proxy.WithSigningKeyNames([]string{t.supplierOperatorPingAllKeyName}), + proxy.WithSigningKeyNames([]string{supplierOperatorKeyName}), proxy.WithServicesConfigMap(t.servicesConfigMap), ) require.NoError(t.T(), err) @@ -696,7 +694,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { } relayProxyBehavior := append(t.relayerProxyBehavior, []func(*testproxy.TestBehavior){ - testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), + testproxy.WithDefaultSupplier(supplierOperatorKeyName, supplierEndpoints), testproxy.WithServicesConfigMap(servicesConfigMap), }...) @@ -710,7 +708,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { rp, err := proxy.NewRelayerProxy( testBehavoirs.Deps, - proxy.WithSigningKeyNames([]string{t.supplierOperatorPingAllKeyName}), + proxy.WithSigningKeyNames([]string{supplierOperatorKeyName}), proxy.WithServicesConfigMap(servicesConfigMap), ) require.NoError(t.T(), err) @@ -775,7 +773,7 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAtStartup() { } relayProxyBehavior := append(t.relayerProxyBehavior, []func(*testproxy.TestBehavior){ - testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), + testproxy.WithDefaultSupplier(supplierOperatorKeyName, supplierEndpoints), testproxy.WithServicesConfigMap(servicesConfigMap), }...) @@ -789,7 +787,7 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAtStartup() { rp, err := proxy.NewRelayerProxy( test.Deps, - proxy.WithSigningKeyNames([]string{t.supplierOperatorPingAllKeyName}), + proxy.WithSigningKeyNames([]string{supplierOperatorKeyName}), proxy.WithServicesConfigMap(servicesConfigMap), ) require.NoError(t.T(), err) @@ -850,7 +848,7 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() } relayProxyBehavior := append(t.relayerProxyBehavior, []func(*testproxy.TestBehavior){ - testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), + testproxy.WithDefaultSupplier(supplierOperatorKeyName, supplierEndpoints), testproxy.WithServicesConfigMap(servicesConfigMap), }...) @@ -864,7 +862,7 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() rp, err := proxy.NewRelayerProxy( test.Deps, - proxy.WithSigningKeyNames([]string{t.supplierOperatorPingAllKeyName}), + proxy.WithSigningKeyNames([]string{supplierOperatorKeyName}), proxy.WithServicesConfigMap(servicesConfigMap), ) require.NoError(t.T(), err) @@ -975,7 +973,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { } relayProxyBehavior := append(t.relayerProxyBehavior, []func(*testproxy.TestBehavior){ - testproxy.WithDefaultSupplier(t.supplierOperatorPingAllKeyName, supplierEndpoints), + testproxy.WithDefaultSupplier(supplierOperatorKeyName, supplierEndpoints), testproxy.WithServicesConfigMap(servicesConfigMap), }...) @@ -989,7 +987,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { rp, err := proxy.NewRelayerProxy( test.Deps, - proxy.WithSigningKeyNames([]string{t.supplierOperatorPingAllKeyName}), + proxy.WithSigningKeyNames([]string{supplierOperatorKeyName}), proxy.WithServicesConfigMap(servicesConfigMap), ) require.NoError(t.T(), err) From acdd9d1f4cd9dfa47955313c78918da887e0b729 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 3 Feb 2025 21:04:20 +0100 Subject: [PATCH 51/55] add two separate relay servers for all with multiple servers + improve error checking --- pkg/relayer/proxy/proxy_test.go | 73 +++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/pkg/relayer/proxy/proxy_test.go b/pkg/relayer/proxy/proxy_test.go index 2470578c1..5e77db425 100644 --- a/pkg/relayer/proxy/proxy_test.go +++ b/pkg/relayer/proxy/proxy_test.go @@ -3,6 +3,7 @@ package proxy_test import ( "bytes" "context" + "errors" "fmt" "io" "net" @@ -563,6 +564,7 @@ type RelayProxyPingAllSuite struct { suite.Suite relayerProxyBehavior []func(*testproxy.TestBehavior) servicesConfigMap map[string]*config.RelayMinerServerConfig + supplierEndpoints map[string][]*sharedtypes.SupplierEndpoint } // TestRelayProxyPingAllSuite executes the RelayProxyPingAllSuite test suite. @@ -635,7 +637,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithSingleRelayServer() { go func() { err := rp.Start(ctx) - if http.ErrServerClosed != err { + if !errors.Is(err, http.ErrServerClosed) { require.NoError(t.T(), err) } }() @@ -657,21 +659,52 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { ctx, cancel := context.WithCancel(context.TODO()) defer cancel() - secondRelayMinerAddr := "127.0.0.1:8246" - secondServiceName := "secondservice" + firstRelayMinerAddr := "127.0.0.1:8246" + firstServiceName := "firstService" + secondRelayMinerAddr := "127.0.0.1:8247" + secondServiceName := "secondService" + + newSupplierOperatorKeyName := "newSupplierKeyName" + appPrivateKey := secp256k1.GenPrivKey() // adding supplier endpoint. supplierEndpoints := map[string][]*sharedtypes.SupplierEndpoint{ - secondServiceName: { + firstServiceName: []*sharedtypes.SupplierEndpoint{ { - Url: "http://secondservice:8646", + Url: "http://firstservice:8646", + RpcType: sharedtypes.RPCType_JSON_RPC, + }, + }, + secondServiceName: []*sharedtypes.SupplierEndpoint{ + { + Url: "http://secondservice:8647", RpcType: sharedtypes.RPCType_JSON_RPC, }, }, } servicesConfigMap := map[string]*config.RelayMinerServerConfig{ - secondRelayMinerAddr: { + firstRelayMinerAddr: &config.RelayMinerServerConfig{ + ServerType: config.RelayMinerServerTypeHTTP, + ListenAddress: firstRelayMinerAddr, + SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ + firstServiceName: { + ServiceId: firstServiceName, + ServerType: config.RelayMinerServerTypeHTTP, + ServiceConfig: &config.RelayMinerSupplierServiceConfig{ + BackendUrl: &url.URL{ + Scheme: "http", + Host: "127.0.0.1:8646", + Path: "/", + }, + }, + PubliclyExposedEndpoints: []string{ + "firstservice", + }, + }, + }, + }, + secondRelayMinerAddr: &config.RelayMinerServerConfig{ ServerType: config.RelayMinerServerTypeHTTP, ListenAddress: secondRelayMinerAddr, SupplierConfigsMap: map[string]*config.RelayMinerSupplierConfig{ @@ -681,7 +714,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { ServiceConfig: &config.RelayMinerSupplierServiceConfig{ BackendUrl: &url.URL{ Scheme: "http", - Host: "127.0.0.1:8646", + Host: "127.0.0.1:8647", Path: "/", }, }, @@ -693,29 +726,27 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllWithMultipleRelayServers() { }, } - relayProxyBehavior := append(t.relayerProxyBehavior, []func(*testproxy.TestBehavior){ - testproxy.WithDefaultSupplier(supplierOperatorKeyName, supplierEndpoints), + relayerProxyBehavior := []func(*testproxy.TestBehavior){ + testproxy.WithRelayerProxyDependenciesForBlockHeight(newSupplierOperatorKeyName, 1), + testproxy.WithDefaultSupplier(newSupplierOperatorKeyName, supplierEndpoints), testproxy.WithServicesConfigMap(servicesConfigMap), - }...) - - testBehavoirs := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), relayProxyBehavior...) - - // copying the default relayminer in the test service config - // map for the relay proxy. - for k, v := range t.servicesConfigMap { - servicesConfigMap[k] = v + testproxy.WithDefaultApplication(appPrivateKey), + testproxy.WithDefaultSessionSupplier(newSupplierOperatorKeyName, defaultService, appPrivateKey), + testproxy.WithRelayMeter(), } + testBehavoirs := testproxy.NewRelayerProxyTestBehavior(ctx, t.T(), relayerProxyBehavior...) + rp, err := proxy.NewRelayerProxy( testBehavoirs.Deps, - proxy.WithSigningKeyNames([]string{supplierOperatorKeyName}), + proxy.WithSigningKeyNames([]string{newSupplierOperatorKeyName}), proxy.WithServicesConfigMap(servicesConfigMap), ) require.NoError(t.T(), err) go func() { err := rp.Start(ctx) - if err != http.ErrServerClosed { + if !errors.Is(err, http.ErrServerClosed) { require.NoError(t.T(), err) } }() @@ -869,7 +900,7 @@ func (t *RelayProxyPingAllSuite) TestNOKPingAllWithPartialFailureAfterStartup() go func() { err := rp.Start(ctx) - if err != http.ErrServerClosed { + if !errors.Is(err, http.ErrServerClosed) { require.NoError(t.T(), err) } }() @@ -994,7 +1025,7 @@ func (t *RelayProxyPingAllSuite) TestOKPingAllDifferentEndpoint() { go func() { err := rp.Start(ctx) - if err != http.ErrServerClosed { + if !errors.Is(err, http.ErrServerClosed) { require.NoError(t.T(), err) } }() From 2f2d9ccfd4d14d14821de118f9acbc9190379e15 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Mon, 3 Feb 2025 21:11:56 +0100 Subject: [PATCH 52/55] remove unused variables --- pkg/relayer/relayminer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/relayer/relayminer.go b/pkg/relayer/relayminer.go index 645cebe19..d43c371ef 100644 --- a/pkg/relayer/relayminer.go +++ b/pkg/relayer/relayminer.go @@ -150,7 +150,7 @@ func (rel *relayMiner) ServePing(ctx context.Context, network, addr string) erro // ping requests. A single ping request on the relay server broadcasts a // ping to all backing services/data nodes. go func() { - if err := http.Serve(ln, rel.newPinghandlerFn(ctx, ln)); err != nil && !errors.Is(http.ErrServerClosed, err) { + if err := http.Serve(ln, rel.newPinghandlerFn(ctx)); err != nil && !errors.Is(http.ErrServerClosed, err) { rel.logger.Error().Err(err).Msg("ping server unexpectedly closed") } }() @@ -164,7 +164,7 @@ func (rel *relayMiner) ServePing(ctx context.Context, network, addr string) erro return nil } -func (rel *relayMiner) newPinghandlerFn(ctx context.Context, ln net.Listener) http.HandlerFunc { +func (rel *relayMiner) newPinghandlerFn(ctx context.Context) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { rel.logger.Debug().Msg("pinging relay servers...") From f4027a5bed206b1240a9101860f70ea49a2e1de1 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 9 Feb 2025 15:36:08 +0100 Subject: [PATCH 53/55] add TestRelayMiner_NOKPing unit test --- pkg/relayer/relayminer_test.go | 147 +++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index 0186fb270..e8dcf3c11 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -2,13 +2,16 @@ package relayer_test import ( "context" + "errors" "net" "net/http" + "net/url" "path/filepath" "testing" "time" "cosmossdk.io/depinject" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "github.com/pokt-network/poktroll/pkg/observable/channel" @@ -126,3 +129,147 @@ func TestRelayMiner_Ping(t *testing.T) { err = relayminer.Stop(ctx) require.NoError(t, err) } + +func TestRelayMiner_NOKPingTemporaryError(t *testing.T) { + // servedRelaysObs is NEVER published to. It exists to satisfy test mocks. + srObs, _ := channel.NewObservable[*servicetypes.Relay]() + servedRelaysObs := relayer.RelaysObservable(srObs) + + // minedRelaysObs is NEVER published to. It exists to satisfy test mocks. + mrObs, _ := channel.NewObservable[*relayer.MinedRelay]() + minedRelaysObs := relayer.MinedRelaysObservable(mrObs) + + ctx := polyzero.NewLogger().WithContext(context.Background()) + relayerProxyMock := testrelayer.NewMockOneTimeRelayerProxy(ctx, t, servedRelaysObs) + + urlErr := url.Error{ + Op: http.MethodGet, + URL: "http://unix", + Err: &net.DNSError{ + Err: "fake temporary and timeout error", + Name: "example.com", + Server: "8.8.8.8", + IsTemporary: true, + IsTimeout: true, + }, + } + + relayerProxyMock.EXPECT().PingAll(gomock.Eq(ctx)). + Times(1).Return(&urlErr) + + minerMock := testrelayer.NewMockOneTimeMiner( + ctx, t, + servedRelaysObs, + minedRelaysObs, + ) + + relayerSessionsManagerMock := testrelayer.NewMockOneTimeRelayerSessionsManager( + ctx, t, + minedRelaysObs, + ) + + deps := depinject.Supply( + relayerProxyMock, + minerMock, + relayerSessionsManagerMock, + ) + + relayminer, err := relayer.NewRelayMiner(ctx, deps) + require.NoError(t, err) + require.NotNil(t, relayminer) + + err = relayminer.Start(ctx) + require.NoError(t, err) + + time.Sleep(time.Millisecond) + + relayminerSocketPath := filepath.Join(t.TempDir(), "aae252f8-b19d-4bde-bd23-d8f2f6bf4011") + + relayminer.ServePing(ctx, "unix", relayminerSocketPath) + + time.Sleep(time.Millisecond) + + transport := &http.Transport{ + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + return net.Dial("unix", relayminerSocketPath) + }, + } + + // Override transport configuration to adapt the http client to the unix socket listener. + httpClient := http.Client{Transport: transport} + require.NoError(t, err) + + resp, err := httpClient.Get("http://unix") + require.NoError(t, err) + + require.Equal(t, http.StatusGatewayTimeout, resp.StatusCode) + + err = relayminer.Stop(ctx) + require.NoError(t, err) +} + +func TestRelayMiner_NOKPingNonTemporaryError(t *testing.T) { + // servedRelaysObs is NEVER published to. It exists to satisfy test mocks. + srObs, _ := channel.NewObservable[*servicetypes.Relay]() + servedRelaysObs := relayer.RelaysObservable(srObs) + + // minedRelaysObs is NEVER published to. It exists to satisfy test mocks. + mrObs, _ := channel.NewObservable[*relayer.MinedRelay]() + minedRelaysObs := relayer.MinedRelaysObservable(mrObs) + + ctx := polyzero.NewLogger().WithContext(context.Background()) + relayerProxyMock := testrelayer.NewMockOneTimeRelayerProxy(ctx, t, servedRelaysObs) + + relayerProxyMock.EXPECT().PingAll(gomock.Eq(ctx)). + Times(1).Return(errors.New("fake")) + + minerMock := testrelayer.NewMockOneTimeMiner( + ctx, t, + servedRelaysObs, + minedRelaysObs, + ) + + relayerSessionsManagerMock := testrelayer.NewMockOneTimeRelayerSessionsManager( + ctx, t, + minedRelaysObs, + ) + + deps := depinject.Supply( + relayerProxyMock, + minerMock, + relayerSessionsManagerMock, + ) + + relayminer, err := relayer.NewRelayMiner(ctx, deps) + require.NoError(t, err) + require.NotNil(t, relayminer) + + err = relayminer.Start(ctx) + require.NoError(t, err) + + time.Sleep(time.Millisecond) + + relayminerSocketPath := filepath.Join(t.TempDir(), "aae252f8-b19d-4bde-bd23-d8f2f6bf4011") + + relayminer.ServePing(ctx, "unix", relayminerSocketPath) + + time.Sleep(time.Millisecond) + + transport := &http.Transport{ + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + return net.Dial("unix", relayminerSocketPath) + }, + } + + // Override transport configuration to adapt the http client to the unix socket listener. + httpClient := http.Client{Transport: transport} + require.NoError(t, err) + + resp, err := httpClient.Get("http://unix") + require.NoError(t, err) + + require.Equal(t, http.StatusBadGateway, resp.StatusCode) + + err = relayminer.Stop(ctx) + require.NoError(t, err) +} From 6b27a8372c23520ecd1639e2279e9d91343a9729 Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 9 Feb 2025 16:45:30 +0100 Subject: [PATCH 54/55] refactor Relayminer ping test using suite --- pkg/relayer/relayminer_test.go | 137 +++++++++++++++++---------------- 1 file changed, 72 insertions(+), 65 deletions(-) diff --git a/pkg/relayer/relayminer_test.go b/pkg/relayer/relayminer_test.go index e8dcf3c11..7946d5b98 100644 --- a/pkg/relayer/relayminer_test.go +++ b/pkg/relayer/relayminer_test.go @@ -11,12 +11,15 @@ import ( "time" "cosmossdk.io/depinject" + "github.com/cometbft/cometbft/libs/os" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" "github.com/pokt-network/poktroll/pkg/observable/channel" "github.com/pokt-network/poktroll/pkg/polylog/polyzero" "github.com/pokt-network/poktroll/pkg/relayer" + "github.com/pokt-network/poktroll/testutil/mockrelayer" "github.com/pokt-network/poktroll/testutil/testrelayer" servicetypes "github.com/pokt-network/poktroll/x/service/types" ) @@ -64,30 +67,47 @@ func TestRelayMiner_StartAndStop(t *testing.T) { require.NoError(t, err) } -func TestRelayMiner_Ping(t *testing.T) { +type RelayMinerPingSuite struct { + suite.Suite + + servedRelaysObs relayer.RelaysObservable + minedRelaysObs relayer.MinedRelaysObservable + + relayerProxyMock *mockrelayer.MockRelayerProxy + minerMock *mockrelayer.MockMiner + relayerSessionsManagerMock *mockrelayer.MockRelayerSessionsManager +} + +func TestRelayMinerPingSuite(t *testing.T) { + suite.Run(t, new(RelayMinerPingSuite)) +} + +func (t *RelayMinerPingSuite) SetupTest() { // servedRelaysObs is NEVER published to. It exists to satisfy test mocks. srObs, _ := channel.NewObservable[*servicetypes.Relay]() - servedRelaysObs := relayer.RelaysObservable(srObs) + t.servedRelaysObs = relayer.RelaysObservable(srObs) // minedRelaysObs is NEVER published to. It exists to satisfy test mocks. mrObs, _ := channel.NewObservable[*relayer.MinedRelay]() - minedRelaysObs := relayer.MinedRelaysObservable(mrObs) + t.minedRelaysObs = relayer.MinedRelaysObservable(mrObs) +} +func (t *RelayMinerPingSuite) TestOKPingAll() { ctx := polyzero.NewLogger().WithContext(context.Background()) relayerProxyMock := testrelayer.NewMockOneTimeRelayerProxyWithPing( - ctx, t, - servedRelaysObs, + ctx, t.T(), + t.servedRelaysObs, ) minerMock := testrelayer.NewMockOneTimeMiner( - ctx, t, - servedRelaysObs, - minedRelaysObs, + ctx, t.T(), + t.servedRelaysObs, + t.minedRelaysObs, ) relayerSessionsManagerMock := testrelayer.NewMockOneTimeRelayerSessionsManager( - ctx, t, - minedRelaysObs, + ctx, t.T(), + t.minedRelaysObs, ) deps := depinject.Supply( @@ -97,15 +117,15 @@ func TestRelayMiner_Ping(t *testing.T) { ) relayminer, err := relayer.NewRelayMiner(ctx, deps) - require.NoError(t, err) - require.NotNil(t, relayminer) + require.NoError(t.T(), err) + require.NotNil(t.T(), relayminer) err = relayminer.Start(ctx) - require.NoError(t, err) + require.NoError(t.T(), err) time.Sleep(time.Millisecond) - relayminerSocketPath := filepath.Join(t.TempDir(), "relayerminer.ping.sock") + relayminerSocketPath := filepath.Join(t.T().TempDir(), "1d031ace") relayminer.ServePing(ctx, "unix", relayminerSocketPath) @@ -119,28 +139,20 @@ func TestRelayMiner_Ping(t *testing.T) { // Override transport configuration to adapt the http client to the unix socket listener. httpClient := http.Client{Transport: transport} - require.NoError(t, err) + require.NoError(t.T(), err) resp, err := httpClient.Get("http://unix") - require.NoError(t, err) + require.NoError(t.T(), err) - require.Equal(t, http.StatusNoContent, resp.StatusCode) + require.Equal(t.T(), http.StatusNoContent, resp.StatusCode) err = relayminer.Stop(ctx) - require.NoError(t, err) + require.NoError(t.T(), err) } -func TestRelayMiner_NOKPingTemporaryError(t *testing.T) { - // servedRelaysObs is NEVER published to. It exists to satisfy test mocks. - srObs, _ := channel.NewObservable[*servicetypes.Relay]() - servedRelaysObs := relayer.RelaysObservable(srObs) - - // minedRelaysObs is NEVER published to. It exists to satisfy test mocks. - mrObs, _ := channel.NewObservable[*relayer.MinedRelay]() - minedRelaysObs := relayer.MinedRelaysObservable(mrObs) - +func (t *RelayMinerPingSuite) TestNOKPingAllWithTemporaryError() { ctx := polyzero.NewLogger().WithContext(context.Background()) - relayerProxyMock := testrelayer.NewMockOneTimeRelayerProxy(ctx, t, servedRelaysObs) + relayerProxyMock := testrelayer.NewMockOneTimeRelayerProxy(ctx, t.T(), t.servedRelaysObs) urlErr := url.Error{ Op: http.MethodGet, @@ -158,14 +170,14 @@ func TestRelayMiner_NOKPingTemporaryError(t *testing.T) { Times(1).Return(&urlErr) minerMock := testrelayer.NewMockOneTimeMiner( - ctx, t, - servedRelaysObs, - minedRelaysObs, + ctx, t.T(), + t.servedRelaysObs, + t.minedRelaysObs, ) relayerSessionsManagerMock := testrelayer.NewMockOneTimeRelayerSessionsManager( - ctx, t, - minedRelaysObs, + ctx, t.T(), + t.minedRelaysObs, ) deps := depinject.Supply( @@ -175,17 +187,20 @@ func TestRelayMiner_NOKPingTemporaryError(t *testing.T) { ) relayminer, err := relayer.NewRelayMiner(ctx, deps) - require.NoError(t, err) - require.NotNil(t, relayminer) + require.NoError(t.T(), err) + require.NotNil(t.T(), relayminer) err = relayminer.Start(ctx) - require.NoError(t, err) + require.NoError(t.T(), err) time.Sleep(time.Millisecond) - relayminerSocketPath := filepath.Join(t.TempDir(), "aae252f8-b19d-4bde-bd23-d8f2f6bf4011") + relayminerSocketPath := filepath.Join(t.T().TempDir(), "5478a402") - relayminer.ServePing(ctx, "unix", relayminerSocketPath) + err = relayminer.ServePing(ctx, "unix", relayminerSocketPath) + require.NoError(t.T(), err) + + require.True(t.T(), os.FileExists(relayminerSocketPath)) time.Sleep(time.Millisecond) @@ -197,41 +212,33 @@ func TestRelayMiner_NOKPingTemporaryError(t *testing.T) { // Override transport configuration to adapt the http client to the unix socket listener. httpClient := http.Client{Transport: transport} - require.NoError(t, err) + require.NoError(t.T(), err) resp, err := httpClient.Get("http://unix") - require.NoError(t, err) + require.NoError(t.T(), err) - require.Equal(t, http.StatusGatewayTimeout, resp.StatusCode) + require.Equal(t.T(), http.StatusGatewayTimeout, resp.StatusCode) err = relayminer.Stop(ctx) - require.NoError(t, err) + require.NoError(t.T(), err) } -func TestRelayMiner_NOKPingNonTemporaryError(t *testing.T) { - // servedRelaysObs is NEVER published to. It exists to satisfy test mocks. - srObs, _ := channel.NewObservable[*servicetypes.Relay]() - servedRelaysObs := relayer.RelaysObservable(srObs) - - // minedRelaysObs is NEVER published to. It exists to satisfy test mocks. - mrObs, _ := channel.NewObservable[*relayer.MinedRelay]() - minedRelaysObs := relayer.MinedRelaysObservable(mrObs) - +func (t *RelayMinerPingSuite) NOKPingWithoutTemporaryError() { ctx := polyzero.NewLogger().WithContext(context.Background()) - relayerProxyMock := testrelayer.NewMockOneTimeRelayerProxy(ctx, t, servedRelaysObs) + relayerProxyMock := testrelayer.NewMockOneTimeRelayerProxy(ctx, t.T(), t.servedRelaysObs) relayerProxyMock.EXPECT().PingAll(gomock.Eq(ctx)). Times(1).Return(errors.New("fake")) minerMock := testrelayer.NewMockOneTimeMiner( - ctx, t, - servedRelaysObs, - minedRelaysObs, + ctx, t.T(), + t.servedRelaysObs, + t.minedRelaysObs, ) relayerSessionsManagerMock := testrelayer.NewMockOneTimeRelayerSessionsManager( - ctx, t, - minedRelaysObs, + ctx, t.T(), + t.minedRelaysObs, ) deps := depinject.Supply( @@ -241,15 +248,15 @@ func TestRelayMiner_NOKPingNonTemporaryError(t *testing.T) { ) relayminer, err := relayer.NewRelayMiner(ctx, deps) - require.NoError(t, err) - require.NotNil(t, relayminer) + require.NoError(t.T(), err) + require.NotNil(t.T(), relayminer) err = relayminer.Start(ctx) - require.NoError(t, err) + require.NoError(t.T(), err) time.Sleep(time.Millisecond) - relayminerSocketPath := filepath.Join(t.TempDir(), "aae252f8-b19d-4bde-bd23-d8f2f6bf4011") + relayminerSocketPath := filepath.Join(t.T().TempDir(), "aae252f8") relayminer.ServePing(ctx, "unix", relayminerSocketPath) @@ -263,13 +270,13 @@ func TestRelayMiner_NOKPingNonTemporaryError(t *testing.T) { // Override transport configuration to adapt the http client to the unix socket listener. httpClient := http.Client{Transport: transport} - require.NoError(t, err) + require.NoError(t.T(), err) resp, err := httpClient.Get("http://unix") - require.NoError(t, err) + require.NoError(t.T(), err) - require.Equal(t, http.StatusBadGateway, resp.StatusCode) + require.Equal(t.T(), http.StatusBadGateway, resp.StatusCode) err = relayminer.Stop(ctx) - require.NoError(t, err) + require.NoError(t.T(), err) } From cc573c70e94d9dfa1e23dda2df8ecadfc68c64cc Mon Sep 17 00:00:00 2001 From: eddyzags Date: Sun, 9 Feb 2025 21:28:49 +0100 Subject: [PATCH 55/55] add optional to ping documentation --- docusaurus/docs/operate/configs/relayminer_config.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docusaurus/docs/operate/configs/relayminer_config.md b/docusaurus/docs/operate/configs/relayminer_config.md index a7ac2a4ae..f9967f009 100644 --- a/docusaurus/docs/operate/configs/relayminer_config.md +++ b/docusaurus/docs/operate/configs/relayminer_config.md @@ -176,6 +176,8 @@ You can learn how to use that endpoint on the [Performance Troubleshooting](../. ### `ping` +_`Optional`_ + Configures a `ping` server to test the connectivity of all backend URLs. If all the backend URLs are reachable, the endpoint returns a 204 HTTP Code. If one or more backend URLs aren't reachable, the service