From 3dc05ac2ae4af8336df024d48210c9af84f00e2a Mon Sep 17 00:00:00 2001 From: "Jorge S. Cuesta" Date: Wed, 12 Oct 2022 13:29:45 -0400 Subject: [PATCH] Merge: Fix #1457; Fix #1484; Enhance http.Client --- app/query_test.go | 5 ++-- types/config.go | 9 ++++++ x/pocketcore/keeper/service_test.go | 4 ++- x/pocketcore/types/config.go | 3 +- x/pocketcore/types/service.go | 45 ++++++++++++++++------------- x/pocketcore/types/service_test.go | 5 +++- 6 files changed, 45 insertions(+), 26 deletions(-) diff --git a/app/query_test.go b/app/query_test.go index 8eaf37cb4..56115d462 100644 --- a/app/query_test.go +++ b/app/query_test.go @@ -824,7 +824,7 @@ func TestQueryRelay(t *testing.T) { } } -func TestQueryMeshRelayMultipleNodes(t *testing.T) { +func TestQueryRelayMultipleNodes(t *testing.T) { const headerKey = "foo" const headerVal = "bar" @@ -857,7 +857,7 @@ func TestQueryMeshRelayMultipleNodes(t *testing.T) { Post(""). BodyString(expectedRequest). MatchHeader(headerKey, headerVal). - Reply(500). + Reply(200). BodyString(expectedResponse) _, _, cleanup := tc.memoryNodeFn(t, genBz, validators) // setup AAT @@ -945,7 +945,6 @@ func TestQueryMeshRelayMultipleNodes(t *testing.T) { stopCli() gock.Off() } - return }) } diff --git a/types/config.go b/types/config.go index 01df8a5c0..d24327ad8 100644 --- a/types/config.go +++ b/types/config.go @@ -34,6 +34,9 @@ type PocketConfig struct { ValidatorCacheSize int64 `json:"validator_cache_size"` ApplicationCacheSize int64 `json:"application_cache_size"` RPCTimeout int64 `json:"rpc_timeout"` + RPCMaxIdleConns int `json:"rpc_max_idle_conns"` + RPCMaxConnsPerHost int `json:"rpc_max_conns_per_host"` + RPCMaxIdleConnsPerHost int `json:"rpc_max_idle_conns_per_host"` PrometheusAddr string `json:"pocket_prometheus_port"` PrometheusMaxOpenfiles int `json:"prometheus_max_open_files"` MaxClaimAgeForProofRetry int `json:"max_claim_age_for_proof_retry"` @@ -101,6 +104,9 @@ const ( DefaultPocketPrometheusListenAddr = "8083" DefaultPrometheusMaxOpenFile = 3 DefaultRPCTimeout = 30000 + DefaultRPCMaxIdleConns = 1000 + DefaultRPCMaxConnsPerHost = 1000 + DefaultRPCMaxIdleConnsPerHost = 1000 DefaultMaxClaimProofRetryAge = 32 DefaultProofPrevalidation = false DefaultCtxCacheSize = 20 @@ -135,6 +141,9 @@ func DefaultConfig(dataDir string) Config { ValidatorCacheSize: DefaultValidatorCacheSize, ApplicationCacheSize: DefaultApplicationCacheSize, RPCTimeout: DefaultRPCTimeout, + RPCMaxIdleConns: DefaultRPCMaxIdleConns, + RPCMaxConnsPerHost: DefaultRPCMaxConnsPerHost, + RPCMaxIdleConnsPerHost: DefaultRPCMaxIdleConnsPerHost, PrometheusAddr: DefaultPocketPrometheusListenAddr, PrometheusMaxOpenfiles: DefaultPrometheusMaxOpenFile, MaxClaimAgeForProofRetry: DefaultMaxClaimProofRetryAge, diff --git a/x/pocketcore/keeper/service_test.go b/x/pocketcore/keeper/service_test.go index c0d8488f4..d66831b0c 100644 --- a/x/pocketcore/keeper/service_test.go +++ b/x/pocketcore/keeper/service_test.go @@ -66,8 +66,10 @@ func TestKeeper_HandleRelay(t *testing.T) { t.Fatalf(er.Error()) } validRelay.Proof.Signature = hex.EncodeToString(clientSig) + httpClient := types.GetChainsClient() defer gock.Off() // Flush pending mocks after test execution - + defer gock.RestoreClient(httpClient) + gock.InterceptClient(httpClient) gock.New("https://www.google.com:443"). Post("/"). Reply(200). diff --git a/x/pocketcore/types/config.go b/x/pocketcore/types/config.go index 115e789bb..fa2867f07 100644 --- a/x/pocketcore/types/config.go +++ b/x/pocketcore/types/config.go @@ -28,6 +28,7 @@ func InitConfig(chains *HostedBlockchains, logger log.Logger, c types.Config) { ConfigOnce.Do(func() { InitGlobalServiceMetric(chains, logger, c.PocketConfig.PrometheusAddr, c.PocketConfig.PrometheusMaxOpenfiles) }) + InitHttpClient(c.PocketConfig.RPCMaxIdleConns, c.PocketConfig.RPCMaxConnsPerHost, c.PocketConfig.RPCMaxIdleConnsPerHost) InitPocketNodeCaches(c, logger) InitEvidenceWorker(c, logger) GlobalPocketConfig = c.PocketConfig @@ -40,7 +41,7 @@ func InitConfig(chains *HostedBlockchains, logger log.Logger, c types.Config) { SetRPCTimeout(c.PocketConfig.RPCTimeout) } -func InitEvidenceWorker(c types.Config, logger log.Logger) { +func InitEvidenceWorker(_ types.Config, logger log.Logger) { panicHandler := func(p interface{}) { logger.Error(fmt.Sprintf("evidence storage task panicked: %v", p)) } diff --git a/x/pocketcore/types/service.go b/x/pocketcore/types/service.go index 145ff3ad6..ce8e52966 100644 --- a/x/pocketcore/types/service.go +++ b/x/pocketcore/types/service.go @@ -28,31 +28,36 @@ type Relay struct { Proof RelayProof `json:"proof"` // the authentication scheme needed for work } -func getClient() *http.Client { +func GetChainsClient() *http.Client { if chainHttpClient == nil { - var chainsTransport *http.Transport - t, ok := http.DefaultTransport.(*http.Transport) - if ok { - chainsTransport = t.Clone() - // this params may could be handled by config.json, but how much people know about this? - // tbd: figure out the right values to this, rn the priority is stop recreating new http client and connections. - chainsTransport.MaxIdleConns = 1000 - chainsTransport.MaxConnsPerHost = 1000 - chainsTransport.MaxIdleConnsPerHost = 1000 - } // if not ok, probably is because is *gock.Transport - test only - - chainHttpClient = &http.Client{ - Timeout: globalRPCTimeout * time.Second, - } - - if chainsTransport != nil { - chainHttpClient.Transport = chainsTransport - } + InitHttpClient(1000, 1000, 1000) } return chainHttpClient } +func InitHttpClient(maxIdleConns, maxConnsPerHost, maxIdleConnsPerHost int) { + var chainsTransport *http.Transport + + t, ok := http.DefaultTransport.(*http.Transport) + if ok { + chainsTransport = t.Clone() + // this params may could be handled by config.json, but how much people know about this? + // tbd: figure out the right values to this, rn the priority is stop recreating new http client and connections. + chainsTransport.MaxIdleConns = maxIdleConns + chainsTransport.MaxConnsPerHost = maxConnsPerHost + chainsTransport.MaxIdleConnsPerHost = maxIdleConnsPerHost + } // if not ok, probably is because is *gock.Transport - test only + + chainHttpClient = &http.Client{ + Timeout: globalRPCTimeout * time.Second, + } + + if chainsTransport != nil { + chainHttpClient.Transport = chainsTransport + } +} + // "Validate" - Checks the validity of a relay request using store data func (r *Relay) Validate(ctx sdk.Ctx, posKeeper PosKeeper, appsKeeper AppsKeeper, pocketKeeper PocketKeeper, hb *HostedBlockchains, sessionBlockHeight int64, node *PocketNode) (maxPossibleRelays sdk.BigInt, err sdk.Error) { // validate payload @@ -345,7 +350,7 @@ func executeHTTPRequest(payload, url, userAgent string, basicAuth BasicAuth, met } } // execute the request - resp, err := getClient().Do(req) + resp, err := GetChainsClient().Do(req) if err != nil { return "", err } diff --git a/x/pocketcore/types/service_test.go b/x/pocketcore/types/service_test.go index 8d1f0814f..f3d7a1484 100644 --- a/x/pocketcore/types/service_test.go +++ b/x/pocketcore/types/service_test.go @@ -172,8 +172,10 @@ func TestRelay_Execute(t *testing.T) { }, } validRelay.Proof.RequestHash = validRelay.RequestHashString() + httpClient := GetChainsClient() defer gock.Off() // Flush pending mocks after test execution - + defer gock.RestoreClient(httpClient) + gock.InterceptClient(httpClient) gock.New("https://server.com"). Post("/relay"). Reply(200). @@ -185,6 +187,7 @@ func TestRelay_Execute(t *testing.T) { URL: "https://server.com/relay/", }}, } + response, err := validRelay.Execute(&hb, &nodeAddr) assert.True(t, err == nil) assert.Equal(t, response, "bar")