diff --git a/README.md b/README.md index a6c110464..f5308ec26 100644 --- a/README.md +++ b/README.md @@ -565,8 +565,6 @@ See the recommended enabled configuration below: "debug": false, // Web server port. "server-address": ":9092", - // Endpoint timeout duration. - "timeout-duration-secs": 2, // Log file to write to. "logger-filename": "sqs.log", // Flag indicating whether this is a production logger. @@ -577,6 +575,8 @@ See the recommended enabled configuration below: "grpc-gateway-endpoint": "http://localhost:26657", // Chain ID "chain-id": "osmosis-1", + // Chain assets URL + "chain-registry-assets-url": "https://raw.githubusercontent.com/osmosis-labs/assetlists/main/osmosis-1/generated/frontend/assetlist.json", // Router-specific configuration "router": { // Pool IDs that are prioritized in the router. @@ -587,22 +587,22 @@ See the recommended enabled configuration below: "max-routes": 20, // Maximum number of routes to split across. "max-split-routes": 3, - // Maximum number of iterations to split a route across. - "max-split-iterations": 10, // Minimum liquidity capitalization for a pool to be considered in the router. // The denomination assumed is pricing.default-quote-human-denom. "min-liquidity-cap": 100, // Whether to enable route caching "route-cache-enabled": true, + // The number of milliseconds to cache candidate routes for before expiry. + "candidate-route-cache-expiry-seconds": 1200, // How long the route is cached for before expiry in seconds. - "route-cache-expiry-seconds": 600 + "ranked-route-cache-expiry-seconds": 600 }, "pools": { // Code IDs of Transmuter CosmWasm pools that // are supported "transmuter-code-ids": [148, 254], // Code IDs of generalized CosmWasm pools that - // are suported. Note that these pools make network + // are supported. Note that these pools make network // requests to chain for quote estimation. As a result, // they are excluded from split routes. "general-cosmwasm-code-ids": [] @@ -613,14 +613,56 @@ See the recommended enabled configuration below: "cache-expiry-ms": 2000, // The default quote chain denom. // 0 stands for chain. 1 for Coingecko. - // Currently, only on-chain is supported. "default-source": "0", // The default quote chain denom. - "default-quote-human-denom": "usdc" + "default-quote-human-denom": "usdc", + // Overrides provided in "router" configuration. + "max-pools-per-route": 4, + // Overrides provided in "router" configuration. + "max-routes": 20, + // Overrides provided in "router" configuration. + "min-pool-liquidity-cap": 100, + // Coingecko URL endpoint. + "coingecko-url": "https://prices.osmosis.zone/api/v3/simple/price", + // Coingecko quote currency for fetching prices. + "coingecko-quote-currency": "usd" }, - // Whether to enable routes cache overwrite. An overwrite can be set via - // the following endpoint: POST `/router/overwrite-route` - "enable-overwrite-routes-cache": false + "grpc-ingester": { + // Flag to enable the GRPC ingester server + "enabled": true, + // The maximum number of bytes to receive in a single GRPC message + "max-receive-msg-size-bytes": 26214400, + // The address of the GRPC ingester server + "server-address": ":50051", + // The number of seconds to wait for a connection to the server. + "server-connection-timeout-seconds": 10 + }, + "otel": { + // The DSN to use. + "dsn": "", + // The sample rate for event submission in the range [0.0, 1.0]. + // By default, all events are sent. + "sample-rate": 1, + // Enable performance tracing. + "enable-tracing": true, + // The sample rate for profiling traces in the range [0.0, 1.0]. + // This is relative to TracesSampleRate - it is a ratio of profiled traces out of all sampled traces. + "profiles-sample-rate": 1, + // The environment to be sent with events. + "environment": "sqs-dev", + "custom-sample-rate": { + "/router/quote": 1, + "other": 0 + } + }, + "cors": { + // Specifies Access-Control-Allow-Headers header value. + "allowed-headers": "Origin, Accept, Content-Type, X-Requested-With, X-Server-Time, Origin, Accept, Content-Type, X-Requested-With, X-Server-Time, Accept-Encoding, sentry-trace, baggage", + // Specifies Access-Control-Allow-Methods header value. + "allowed-methods": "HEAD, GET, POST, HEAD, GET, POST, DELETE, OPTIONS, PATCH, PUT", + // Specifies Access-Control-Allow-Origin header value. + "allowed-origin": "*" + } } ``` diff --git a/app/sidecar_query_server.go b/app/sidecar_query_server.go index 2f6a1503b..e2b34347c 100644 --- a/app/sidecar_query_server.go +++ b/app/sidecar_query_server.go @@ -141,7 +141,7 @@ func NewSideCarQueryServer(appCodec codec.Codec, config domain.Config, logger lo // Start grpc ingest server if enabled grpcIngesterConfig := config.GRPCIngester - if grpcIngesterConfig.Enabeld { + if grpcIngesterConfig.Enabled { // Get the default quote denom defaultQuoteDenom, err := tokensUseCase.GetChainDenom(config.Pricing.DefaultQuoteHumanDenom) if err != nil { diff --git a/app/sqs_config.go b/app/sqs_config.go index 55e8168a8..4892a204c 100644 --- a/app/sqs_config.go +++ b/app/sqs_config.go @@ -6,9 +6,6 @@ import ( // DefaultConfig defines the default config for the sidecar query server. var DefaultConfig = domain.Config{ - StorageHost: "localhost", - StoragePort: "6379", - ServerAddress: ":9092", LoggerFilename: "sqs.log", @@ -24,13 +21,10 @@ var DefaultConfig = domain.Config{ MaxPoolsPerRoute: 4, MaxRoutes: 5, MaxSplitRoutes: 3, - MaxSplitIterations: 10, MinPoolLiquidityCap: 100, // The denomination assummed is set by Pricing.DefaultHumanDenom RouteCacheEnabled: false, CandidateRouteCacheExpirySeconds: 600, // 10 minutes RankedRouteCacheExpirySeconds: 300, // 5 minutes - - EnableOverwriteRoutesCache: false, }, Pools: &domain.PoolsConfig{ // This is what we have on mainnet as of Jan 2024. diff --git a/config-testnet.json b/config-testnet.json index 4aea85a19..6293568b7 100644 --- a/config-testnet.json +++ b/config-testnet.json @@ -1,7 +1,6 @@ { "debug": true, "server-address": ":9092", - "timeout-duration-secs": 2, "logger-filename": "sqs.log", "logger-is-production": true, "logger-level": "info", @@ -13,7 +12,6 @@ "max-pools-per-route": 4, "max-routes": 20, "max-split-routes": 3, - "max-split-iterations": 10, "min-pool-liquidity-cap": 10, "route-cache-enabled": true, "candidate-route-cache-expiry-seconds": 1200, @@ -49,7 +47,6 @@ "dsn": "", "sample-rate": 1, "enable-tracing": true, - "traces-sample-rate": 1, "profiles-sample-rate": 1, "environment": "production" }, @@ -58,4 +55,4 @@ "allowed-methods": "HEAD, GET, POST, HEAD, GET, POST, DELETE, OPTIONS, PATCH, PUT", "allowed-origins": "*" } -} \ No newline at end of file +} diff --git a/config.json b/config.json index 5097f15fd..a7d9ecc16 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,6 @@ { "debug": true, "server-address": ":9092", - "timeout-duration-secs": 2, "logger-filename": "sqs.log", "logger-is-production": true, "logger-level": "info", @@ -13,7 +12,6 @@ "max-pools-per-route": 4, "max-routes": 20, "max-split-routes": 3, - "max-split-iterations": 10, "min-pool-liquidity-cap": 1000, "route-cache-enabled": true, "candidate-route-cache-expiry-seconds": 1200, @@ -51,7 +49,6 @@ "dsn": "", "sample-rate": 1, "enable-tracing": true, - "traces-sample-rate": 1, "profiles-sample-rate": 1, "environment": "sqs-dev", "custom-sample-rate": { @@ -64,4 +61,4 @@ "allowed-methods": "HEAD, GET, POST, HEAD, GET, POST, DELETE, OPTIONS, PATCH, PUT", "allowed-origin": "*" } -} \ No newline at end of file +} diff --git a/domain/cache/export_test.go b/domain/cache/export_test.go index 03ab5f6cc..02b4be6d3 100644 --- a/domain/cache/export_test.go +++ b/domain/cache/export_test.go @@ -2,4 +2,4 @@ package cache import "time" -const NoExpiration time.Duration = 0 \ No newline at end of file +const NoExpiration time.Duration = 0 diff --git a/domain/config.go b/domain/config.go index fa6e2e7fe..3a4a2a665 100644 --- a/domain/config.go +++ b/domain/config.go @@ -2,10 +2,6 @@ package domain // Config defines the config for the sidecar query server. type Config struct { - // Storage defines the storage host and port. - StorageHost string `mapstructure:"db-host"` - StoragePort string `mapstructure:"db-port"` - // Defines the web server configuration. ServerAddress string `mapstructure:"server-address"` @@ -17,7 +13,7 @@ type Config struct { ChainGRPCGatewayEndpoint string `mapstructure:"grpc-gateway-endpoint"` ChainID string `mapstructure:"chain-id"` - // Chain registry assets firl URL. + // Chain registry assets URL. ChainRegistryAssetsFileURL string `mapstructure:"chain-registry-assets-url"` // Router encapsulates the router config. @@ -28,10 +24,13 @@ type Config struct { Pricing *PricingConfig `mapstructure:"pricing"` + // GRPC ingester server configuration. GRPCIngester *GRPCIngesterConfig `mapstructure:"grpc-ingester"` + // OpenTelemetry configuration. OTEL *OTELConfig `mapstructure:"otel"` + // SideCarQueryServer CORS configuration. CORS *CORSConfig `mapstructure:"cors"` } @@ -40,18 +39,29 @@ type EndpointOTELConfig struct { Other float64 `mapstructure:"other"` } +// OTELConfig represents OpenTelemetry configuration. type OTELConfig struct { - DSN string `mapstructure:"dsn"` - SampleRate float64 `mapstructure:"sample-rate"` - EnableTracing bool `mapstructure:"enable-tracing"` - TracesSampleRate float64 `mapstructure:"traces-sample-rate"` - ProfilesSampleRate float64 `mapstructure:"profiles-sample-rate"` - Environment string `mapstructure:"environment"` - CustomSampleRate EndpointOTELConfig `mapstructure:"custom-sample-rate"` + // The DSN to use. + DSN string `mapstructure:"dsn"` + // The sample rate for event submission in the range [0.0, 1.0]. + // By default, all events are sent. + SampleRate float64 `mapstructure:"sample-rate"` + // Enable performance tracing. + EnableTracing bool `mapstructure:"enable-tracing"` + // The sample rate for profiling traces in the range [0.0, 1.0]. + // This is relative to TracesSampleRate - it is a ratio of profiled traces out of all sampled traces. + ProfilesSampleRate float64 `mapstructure:"profiles-sample-rate"` + // The environment to be sent with events. + Environment string `mapstructure:"environment"` + CustomSampleRate EndpointOTELConfig `mapstructure:"custom-sample-rate"` } +// CORSConfig represents HTTP CORS headers configuration. type CORSConfig struct { + // Specifies Access-Control-Allow-Headers header value. AllowedHeaders string `mapstructure:"allowed-headers"` + // Specifies Access-Control-Allow-Methods header value. AllowedMethods string `mapstructure:"allowed-methods"` - AllowedOrigin string `mapstructure:"allowed-origin"` + // Specifies Access-Control-Allow-Origin header value. + AllowedOrigin string `mapstructure:"allowed-origin"` } diff --git a/domain/ingester.go b/domain/ingester.go index d19244128..ab9e07f3b 100644 --- a/domain/ingester.go +++ b/domain/ingester.go @@ -2,7 +2,7 @@ package domain type GRPCIngesterConfig struct { // Flag to enable the GRPC ingester server - Enabeld bool `mapstructure:"enabled"` + Enabled bool `mapstructure:"enabled"` // The maximum number of bytes to receive in a single GRPC message MaxReceiveMsgSizeBytes int `mapstructure:"max-receive-msg-size-bytes"` diff --git a/domain/pricing.go b/domain/pricing.go index 109533c36..e76c2f829 100644 --- a/domain/pricing.go +++ b/domain/pricing.go @@ -102,11 +102,16 @@ type PricingConfig struct { CacheExpiryMs int `mapstructure:"cache-expiry-ms"` // The default quote chain denom. + // 0 stands for chain. 1 for Coingecko. DefaultSource PricingSourceType `mapstructure:"default-source"` // The default quote chain denom. DefaultQuoteHumanDenom string `mapstructure:"default-quote-human-denom"` - CoingeckoUrl string `mapstructure:"coingecko-url"` + + // Coingecko URL endpoint. + CoingeckoUrl string `mapstructure:"coingecko-url"` + + // Coingecko quote currency for fetching prices. CoingeckoQuoteCurrency string `mapstructure:"coingecko-quote-currency"` MaxPoolsPerRoute int `mapstructure:"max-pools-per-route"` diff --git a/domain/router.go b/domain/router.go index 19c5016b9..6ca41c35f 100644 --- a/domain/router.go +++ b/domain/router.go @@ -64,25 +64,41 @@ type Quote interface { String() string } +// Router-specific configuration type RouterConfig struct { - PreferredPoolIDs []uint64 `mapstructure:"preferred-pool-ids"` - MaxPoolsPerRoute int `mapstructure:"max-pools-per-route"` - MaxRoutes int `mapstructure:"max-routes"` - MaxSplitRoutes int `mapstructure:"max-split-routes"` - MaxSplitIterations int `mapstructure:"max-split-iterations"` - // MinPoolLiquidityCap is the minimum liquidity capitalization required for a pool to be considered in the route. - MinPoolLiquidityCap int `mapstructure:"min-pool-liquidity-cap"` - RouteUpdateHeightInterval int `mapstructure:"route-update-height-interval"` - RouteCacheEnabled bool `mapstructure:"route-cache-enabled"` + // Pool IDs that are prioritized in the router. + PreferredPoolIDs []uint64 `mapstructure:"preferred-pool-ids"` + + // Maximum number of pools in one route. + MaxPoolsPerRoute int `mapstructure:"max-pools-per-route"` + + // Maximum number of routes to search for. + MaxRoutes int `mapstructure:"max-routes"` + + // Maximum number of routes to split across. + MaxSplitRoutes int `mapstructure:"max-split-routes"` + + // Minimum liquidity capitalization for a pool to be considered in the router. + // The denomination assumed is pricing.default-quote-human-denom. + MinPoolLiquidityCap int `mapstructure:"min-pool-liquidity-cap"` + + // Whether to enable route caching + RouteCacheEnabled bool `mapstructure:"route-cache-enabled"` + // The number of milliseconds to cache candidate routes for before expiry. CandidateRouteCacheExpirySeconds int `mapstructure:"candidate-route-cache-expiry-seconds"` - RankedRouteCacheExpirySeconds int `mapstructure:"ranked-route-cache-expiry-seconds"` - // Flag indicating whether we should have a cache for overwrite routes enabled. - EnableOverwriteRoutesCache bool `mapstructure:"enable-overwrite-routes-cache"` + + // How long the route is cached for before expiry in seconds. + RankedRouteCacheExpirySeconds int `mapstructure:"ranked-route-cache-expiry-seconds"` } type PoolsConfig struct { - TransmuterCodeIDs []uint64 `mapstructure:"transmuter-code-ids"` + // Code IDs of Transmuter CosmWasm pools that are supported. + TransmuterCodeIDs []uint64 `mapstructure:"transmuter-code-ids"` + + // Code IDs of generalized CosmWasm pools that are supported. + // NOTE: that these pools make network requests to chain for quote estimation. + // As a result, they are excluded from split routes. GeneralCosmWasmCodeIDs []uint64 `mapstructure:"general-cosmwasm-code-ids"` } @@ -100,10 +116,9 @@ type RouterState struct { // This is useful for pricing where we may want to use different parameters than the default config. // With pricing, it is desired to use more pools with lower min liquidity parameter. type RouterOptions struct { - MaxPoolsPerRoute int - MaxRoutes int - MaxSplitRoutes int - MaxSplitIterations int + MaxPoolsPerRoute int + MaxRoutes int + MaxSplitRoutes int // MinPoolLiquidityCap is the minimum liquidity capitalization required for a pool to be considered in the route. MinPoolLiquidityCap int // The number of milliseconds to cache candidate routes for before expiry. diff --git a/ingest/usecase/export_test.go b/ingest/usecase/export_test.go index 96abd9d50..241c6184d 100644 --- a/ingest/usecase/export_test.go +++ b/ingest/usecase/export_test.go @@ -3,4 +3,3 @@ package usecase type ( IngestUseCaseImpl = ingestUseCase ) - diff --git a/router/repository/memory_router_repository_test.go b/router/repository/memory_router_repository_test.go index c9db93a6c..4c0b6f5e1 100644 --- a/router/repository/memory_router_repository_test.go +++ b/router/repository/memory_router_repository_test.go @@ -131,7 +131,7 @@ func (suite *RouteRepositoryChatGPTTestSuite) TestSetTakerFee() { for _, tt := range tests { suite.Run(tt.name, func() { - suite.repository.SetTakerFee( tt.denom0, tt.denom1, tt.fee) + suite.repository.SetTakerFee(tt.denom0, tt.denom1, tt.fee) fee, ok := suite.repository.GetTakerFee(tt.denom0, tt.denom1) assert.True(suite.T(), ok) @@ -163,7 +163,7 @@ func (suite *RouteRepositoryChatGPTTestSuite) TestSetTakerFees() { for _, tt := range tests { suite.Run(tt.name, func() { - suite.repository.SetTakerFees( tt.takerFees) + suite.repository.SetTakerFees(tt.takerFees) fees := suite.repository.GetAllTakerFees() assert.Equal(suite.T(), tt.expectedFees, fees) diff --git a/router/usecase/router_usecase.go b/router/usecase/router_usecase.go index 39c382503..63258299f 100644 --- a/router/usecase/router_usecase.go +++ b/router/usecase/router_usecase.go @@ -117,7 +117,6 @@ func (r *routerUseCaseImpl) GetOptimalQuote(ctx context.Context, tokenIn sdk.Coi options := domain.RouterOptions{ MaxPoolsPerRoute: r.defaultConfig.MaxPoolsPerRoute, MaxRoutes: r.defaultConfig.MaxRoutes, - MaxSplitIterations: r.defaultConfig.MaxSplitIterations, MinPoolLiquidityCap: r.defaultConfig.MinPoolLiquidityCap, CandidateRouteCacheExpirySeconds: r.defaultConfig.CandidateRouteCacheExpirySeconds, RankedRouteCacheExpirySeconds: r.defaultConfig.RankedRouteCacheExpirySeconds, diff --git a/router/usecase/router_usecase_test.go b/router/usecase/router_usecase_test.go index ededea998..328954a2a 100644 --- a/router/usecase/router_usecase_test.go +++ b/router/usecase/router_usecase_test.go @@ -146,10 +146,8 @@ func (s *RouterTestSuite) TestHandleRoutes() { MaxRoutes: 4, // These configs are not relevant for this test. - PreferredPoolIDs: []uint64{}, - MaxSplitIterations: 10, - MinPoolLiquidityCap: minPoolLiquidityCap, - RouteUpdateHeightInterval: 10, + PreferredPoolIDs: []uint64{}, + MinPoolLiquidityCap: minPoolLiquidityCap, } ) diff --git a/router/usecase/routertesting/suite.go b/router/usecase/routertesting/suite.go index 8a70fd06d..24c4e66d5 100644 --- a/router/usecase/routertesting/suite.go +++ b/router/usecase/routertesting/suite.go @@ -150,14 +150,12 @@ var ( absolutePathToStateFiles = "" DefaultRouterConfig = domain.RouterConfig{ - PreferredPoolIDs: []uint64{}, - MaxRoutes: 4, - MaxPoolsPerRoute: 4, - MaxSplitRoutes: 4, - MaxSplitIterations: 10, - MinPoolLiquidityCap: 20000, - RouteUpdateHeightInterval: 0, - RouteCacheEnabled: true, + PreferredPoolIDs: []uint64{}, + MaxRoutes: 4, + MaxPoolsPerRoute: 4, + MaxSplitRoutes: 4, + MinPoolLiquidityCap: 20000, + RouteCacheEnabled: true, } DefaultPoolsConfig = domain.PoolsConfig{