diff --git a/CHANGELOG.md b/CHANGELOG.md index da6ef108f..2a7d15d9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ # Changelog +## v25.4.1 + +- Resolve goroutine leak stemming from creating a grpc connection for every cosmwasm pool in route. Share one connection. + ## v25.4.0 - Remove spread factor from fee as it is included in the price impact diff --git a/app/sidecar_query_server.go b/app/sidecar_query_server.go index dc5fa8388..83996d160 100644 --- a/app/sidecar_query_server.go +++ b/app/sidecar_query_server.go @@ -122,7 +122,10 @@ func NewSideCarQueryServer(appCodec codec.Codec, config domain.Config, logger lo } // Initialize pools repository, usecase and HTTP handler - poolsUseCase := poolsUseCase.NewPoolsUsecase(config.Pools, config.ChainGRPCGatewayEndpoint, routerRepository, tokensUseCase.GetChainScalingFactorByDenomMut, logger) + poolsUseCase, err := poolsUseCase.NewPoolsUsecase(config.Pools, config.ChainGRPCGatewayEndpoint, routerRepository, tokensUseCase.GetChainScalingFactorByDenomMut, logger) + if err != nil { + return nil, err + } // Initialize candidate route searcher candidateRouteSearcher := routerUseCase.NewCandidateRouteFinder(routerRepository, logger) diff --git a/domain/mocks/pools_usecase_mock.go b/domain/mocks/pools_usecase_mock.go index 3feeccc41..cd9d664b5 100644 --- a/domain/mocks/pools_usecase_mock.go +++ b/domain/mocks/pools_usecase_mock.go @@ -93,7 +93,9 @@ func (pm *PoolsUsecaseMock) GetRoutesFromCandidates(candidateRoutes sqsdomain.Ca } // TODO: note that taker fee is force set to zero - routablePool, err := pools.NewRoutablePool(foundPool, candidatePool.TokenOutDenom, osmomath.ZeroDec(), domain.CosmWasmPoolRouterConfig{}, domain.UnsetScalingFactorGetterCb) + routablePool, err := pools.NewRoutablePool(foundPool, candidatePool.TokenOutDenom, osmomath.ZeroDec(), pools.CosmWasmPoolsParams{ + ScalingFactorGetterCb: domain.UnsetScalingFactorGetterCb, + }) if err != nil { return nil, err } diff --git a/pools/usecase/pools_usecase.go b/pools/usecase/pools_usecase.go index 67dcd104a..d60907597 100644 --- a/pools/usecase/pools_usecase.go +++ b/pools/usecase/pools_usecase.go @@ -8,9 +8,13 @@ import ( "sync" "cosmossdk.io/math" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/osmosis-labs/sqs/log" "github.com/osmosis-labs/sqs/sqsdomain" + "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "github.com/osmosis-labs/sqs/domain" "github.com/osmosis-labs/sqs/domain/mvc" @@ -32,11 +36,10 @@ type orderBookEntry struct { type poolsUseCase struct { pools sync.Map routerRepository routerrepo.RouterRepository - cosmWasmConfig domain.CosmWasmPoolRouterConfig canonicalOrderBookForBaseQuoteDenom sync.Map - scalingFactorGetterCb domain.ScalingFactorGetterCb + cosmWasmPoolsParams pools.CosmWasmPoolsParams logger log.Logger } @@ -49,7 +52,7 @@ const ( ) // NewPoolsUsecase will create a new pools use case object -func NewPoolsUsecase(poolsConfig *domain.PoolsConfig, chainGRPCGatewayEndpoint string, routerRepository routerrepo.RouterRepository, scalingFactorGetterCb domain.ScalingFactorGetterCb, logger log.Logger) *poolsUseCase { +func NewPoolsUsecase(poolsConfig *domain.PoolsConfig, chainGRPCGatewayEndpoint string, routerRepository routerrepo.RouterRepository, scalingFactorGetterCb domain.ScalingFactorGetterCb, logger log.Logger) (*poolsUseCase, error) { transmuterCodeIDsMap := make(map[uint64]struct{}, len(poolsConfig.TransmuterCodeIDs)) for _, codeId := range poolsConfig.TransmuterCodeIDs { transmuterCodeIDsMap[codeId] = struct{}{} @@ -70,21 +73,31 @@ func NewPoolsUsecase(poolsConfig *domain.PoolsConfig, chainGRPCGatewayEndpoint s generalizedCosmWasmCodeIDsMap[codeId] = struct{}{} } + wasmClient, err := initializeWasmClient(chainGRPCGatewayEndpoint) + if err != nil { + return nil, err + } + return &poolsUseCase{ - cosmWasmConfig: domain.CosmWasmPoolRouterConfig{ - TransmuterCodeIDs: transmuterCodeIDsMap, - AlloyedTransmuterCodeIDs: alloyedTransmuterCodeIDsMap, - OrderbookCodeIDs: orderbookCodeIDsMap, - GeneralCosmWasmCodeIDs: generalizedCosmWasmCodeIDsMap, - ChainGRPCGatewayEndpoint: chainGRPCGatewayEndpoint, - }, + pools: sync.Map{}, + routerRepository: routerRepository, - pools: sync.Map{}, - routerRepository: routerRepository, - scalingFactorGetterCb: scalingFactorGetterCb, + cosmWasmPoolsParams: pools.CosmWasmPoolsParams{ + Config: domain.CosmWasmPoolRouterConfig{ + TransmuterCodeIDs: transmuterCodeIDsMap, + AlloyedTransmuterCodeIDs: alloyedTransmuterCodeIDsMap, + OrderbookCodeIDs: orderbookCodeIDsMap, + GeneralCosmWasmCodeIDs: generalizedCosmWasmCodeIDsMap, + ChainGRPCGatewayEndpoint: chainGRPCGatewayEndpoint, + }, + + WasmClient: wasmClient, + + ScalingFactorGetterCb: scalingFactorGetterCb, + }, logger: logger, - } + }, nil } // GetAllPools returns all pools from the repository. @@ -134,7 +147,7 @@ func (p *poolsUseCase) GetRoutesFromCandidates(candidateRoutes sqsdomain.Candida takerFee = sqsdomain.DefaultTakerFee } - routablePool, err := pools.NewRoutablePool(pool, candidatePool.TokenOutDenom, takerFee, p.cosmWasmConfig, p.scalingFactorGetterCb) + routablePool, err := pools.NewRoutablePool(pool, candidatePool.TokenOutDenom, takerFee, p.cosmWasmPoolsParams) if err != nil { skipErrorRoute = true break @@ -218,7 +231,7 @@ func (p *poolsUseCase) GetPoolSpotPrice(ctx context.Context, poolID uint64, take // N.B.: Empty string for token out denom because it is irrelevant for calculating spot price. // It is only relevant in the context of routing - routablePool, err := pools.NewRoutablePool(pool, "", takerFee, p.cosmWasmConfig, p.scalingFactorGetterCb) + routablePool, err := pools.NewRoutablePool(pool, "", takerFee, p.cosmWasmPoolsParams) if err != nil { return osmomath.BigDec{}, err } @@ -228,7 +241,7 @@ func (p *poolsUseCase) GetPoolSpotPrice(ctx context.Context, poolID uint64, take // IsGeneralCosmWasmCodeID implements mvc.PoolsUsecase. func (p *poolsUseCase) IsGeneralCosmWasmCodeID(codeId uint64) bool { - _, isGenneralCosmWasmCodeID := p.cosmWasmConfig.GeneralCosmWasmCodeIDs[codeId] + _, isGenneralCosmWasmCodeID := p.cosmWasmPoolsParams.Config.GeneralCosmWasmCodeIDs[codeId] return isGenneralCosmWasmCodeID } @@ -439,10 +452,26 @@ func (p *poolsUseCase) GetAllCanonicalOrderbookPoolIDs() ([]domain.CanonicalOrde // GetCosmWasmPoolConfig implements mvc.PoolsUsecase. func (p *poolsUseCase) GetCosmWasmPoolConfig() domain.CosmWasmPoolRouterConfig { - return p.cosmWasmConfig + return p.cosmWasmPoolsParams.Config } // formatBaseQuoteDenom formats the base and quote denom into a single string with a separator. func formatBaseQuoteDenom(baseDenom, quoteDenom string) string { return baseDenom + baseQuoteKeySeparator + quoteDenom } + +// initializeWasmClient initializes the wasm client given the node URI +// Returns error if fails to initialize the client +func initializeWasmClient(grpcGatewayEndpoint string) (wasmtypes.QueryClient, error) { + grpcClient, err := grpc.NewClient(grpcGatewayEndpoint, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithStatsHandler(otelgrpc.NewClientHandler()), + ) + if err != nil { + return nil, err + } + + wasmClient := wasmtypes.NewQueryClient(grpcClient) + + return wasmClient, nil +} diff --git a/pools/usecase/pools_usecase_test.go b/pools/usecase/pools_usecase_test.go index 47f22d905..a7a7d7d38 100644 --- a/pools/usecase/pools_usecase_test.go +++ b/pools/usecase/pools_usecase_test.go @@ -77,7 +77,11 @@ func (s *PoolsUsecaseTestSuite) TestGetRoutesFromCandidates() { // to the wrong type. Note that the default is balancer. brokenChainPool := *defaultPool brokenChainPool.PoolType = poolmanagertypes.CosmWasm - _, err = pools.NewRoutablePool(&brokenChainPool, denomTwo, defaultTakerFee, domain.CosmWasmPoolRouterConfig{}, nil) + + cosmWasmPoolsParams := pools.CosmWasmPoolsParams{ + ScalingFactorGetterCb: domain.UnsetScalingFactorGetterCb, + } + _, err = pools.NewRoutablePool(&brokenChainPool, denomTwo, defaultTakerFee, cosmWasmPoolsParams) // Validate that it is indeed broken. s.Require().Error(err) @@ -201,7 +205,8 @@ func (s *PoolsUsecaseTestSuite) TestGetRoutesFromCandidates() { routerRepo.SetTakerFees(tc.takerFeeMap) // Create pools use case - poolsUsecase := usecase.NewPoolsUsecase(&domain.PoolsConfig{}, "node-uri-placeholder", routerRepo, domain.UnsetScalingFactorGetterCb, &log.NoOpLogger{}) + poolsUsecase, err := usecase.NewPoolsUsecase(&domain.PoolsConfig{}, "node-uri-placeholder", routerRepo, domain.UnsetScalingFactorGetterCb, &log.NoOpLogger{}) + s.Require().NoError(err) poolsUsecase.StorePools(tc.pools) @@ -320,7 +325,7 @@ func (s *PoolsUsecaseTestSuite) TestProcessOrderbookPoolIDForBaseQuote() { tc := tc s.Run(tc.name, func() { - poolsUsecase := newDefaultPoolsUseCase() + poolsUsecase := s.newDefaultPoolsUseCase() // Pre-set invalid data for the base/quote if tc.preStoreInvalidEntry { @@ -428,7 +433,7 @@ func (s *PoolsUsecaseTestSuite) TestStorePools() { } ) - poolsUsecase := newDefaultPoolsUseCase() + poolsUsecase := s.newDefaultPoolsUseCase() // Pre-set invalid data for the base/quote poolsUsecase.StoreInvalidOrderBookEntry(invalidBaseDenom, orderBookQuoteDenom) @@ -465,7 +470,7 @@ func (s *PoolsUsecaseTestSuite) TestStorePools() { // by the StorePools and ProcessOrderbookPoolIDForBaseQuote tests. func (s *PoolsUsecaseTestSuite) TestGetAllCanonicalOrderbooks_HappyPath() { - poolsUseCase := newDefaultPoolsUseCase() + poolsUseCase := s.newDefaultPoolsUseCase() // Denom one and denom two poolsUseCase.StoreValidOrdeBookEntry(denomOne, denomTwo, defaultPoolID, defaultPoolLiquidityCap) @@ -500,14 +505,19 @@ func (s *PoolsUsecaseTestSuite) TestGetAllCanonicalOrderbooks_HappyPath() { } -func (s *PoolsUsecaseTestSuite) newRoutablePool(pool sqsdomain.PoolI, tokenOutDenom string, takerFee osmomath.Dec, cosmWasmPoolIDs domain.CosmWasmPoolRouterConfig) domain.RoutablePool { - routablePool, err := pools.NewRoutablePool(pool, tokenOutDenom, takerFee, cosmWasmPoolIDs, domain.UnsetScalingFactorGetterCb) +func (s *PoolsUsecaseTestSuite) newRoutablePool(pool sqsdomain.PoolI, tokenOutDenom string, takerFee osmomath.Dec, cosmWasmConfig domain.CosmWasmPoolRouterConfig) domain.RoutablePool { + cosmWasmPoolsParams := pools.CosmWasmPoolsParams{ + Config: cosmWasmConfig, + ScalingFactorGetterCb: domain.UnsetScalingFactorGetterCb, + } + routablePool, err := pools.NewRoutablePool(pool, tokenOutDenom, takerFee, cosmWasmPoolsParams) s.Require().NoError(err) return routablePool } -func newDefaultPoolsUseCase() *usecase.PoolsUsecase { +func (s *PoolsUsecaseTestSuite) newDefaultPoolsUseCase() *usecase.PoolsUsecase { routerRepo := routerrepo.New(&log.NoOpLogger{}) - poolsUsecase := usecase.NewPoolsUsecase(&domain.PoolsConfig{}, "node-uri-placeholder", routerRepo, domain.UnsetScalingFactorGetterCb, &log.NoOpLogger{}) + poolsUsecase, err := usecase.NewPoolsUsecase(&domain.PoolsConfig{}, "node-uri-placeholder", routerRepo, domain.UnsetScalingFactorGetterCb, &log.NoOpLogger{}) + s.Require().NoError(err) return poolsUsecase } diff --git a/router/usecase/optimized_routes_test.go b/router/usecase/optimized_routes_test.go index b5e73cb2c..e1a226883 100644 --- a/router/usecase/optimized_routes_test.go +++ b/router/usecase/optimized_routes_test.go @@ -688,7 +688,8 @@ func (s *RouterTestSuite) TestGetCustomQuote_GetCustomDirectQuote_Mainnet_UOSMOU tokensRepositoryMock.SetTakerFees(mainnetState.TakerFeeMap) // Setup pools usecase mock. - poolsUsecase := poolsusecase.NewPoolsUsecase(&domain.PoolsConfig{}, "node-uri-placeholder", tokensRepositoryMock, domain.UnsetScalingFactorGetterCb, &log.NoOpLogger{}) + poolsUsecase, err := poolsusecase.NewPoolsUsecase(&domain.PoolsConfig{}, "node-uri-placeholder", tokensRepositoryMock, domain.UnsetScalingFactorGetterCb, &log.NoOpLogger{}) + s.Require().NoError(err) poolsUsecase.StorePools(mainnetState.Pools) tokenMetaDataHolderMock := &mocks.TokenMetadataHolderMock{} diff --git a/router/usecase/pools/cosmwasm_utils.go b/router/usecase/pools/cosmwasm_utils.go index e4afa7645..a934fe264 100644 --- a/router/usecase/pools/cosmwasm_utils.go +++ b/router/usecase/pools/cosmwasm_utils.go @@ -4,27 +4,16 @@ import ( "context" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/osmosis-labs/sqs/domain" "github.com/osmosis-labs/sqs/sqsdomain/json" - "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" ) -// initializeWasmClient initializes the wasm client given the node URI -// Returns error if fails to initialize the client -func initializeWasmClient(grpcGatewayEndpoint string) (wasmtypes.QueryClient, error) { - grpcClient, err := grpc.NewClient(grpcGatewayEndpoint, - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithStatsHandler(otelgrpc.NewClientHandler()), - ) - if err != nil { - return nil, err - } - - wasmClient := wasmtypes.NewQueryClient(grpcClient) - - return wasmClient, nil +type CosmWasmPoolsParams struct { + Config domain.CosmWasmPoolRouterConfig + WasmClient wasmtypes.QueryClient + ScalingFactorGetterCb domain.ScalingFactorGetterCb } // queryCosmwasmContract queries the cosmwasm contract given the contract address, request and response diff --git a/router/usecase/pools/export_test.go b/router/usecase/pools/export_test.go index 889910b4a..3b9d2c04a 100644 --- a/router/usecase/pools/export_test.go +++ b/router/usecase/pools/export_test.go @@ -19,9 +19,9 @@ type ( func NewRoutableCosmWasmPoolWithCustomModel( pool sqsdomain.PoolI, cosmwasmPool *cwpoolmodel.CosmWasmPool, - cosmWasmConfig domain.CosmWasmPoolRouterConfig, + cosmWasmPoolsParams CosmWasmPoolsParams, tokenOutDenom string, takerFee osmomath.Dec, ) (domain.RoutablePool, error) { - return newRoutableCosmWasmPoolWithCustomModel(pool, cosmwasmPool, cosmWasmConfig, tokenOutDenom, takerFee) + return newRoutableCosmWasmPoolWithCustomModel(pool, cosmwasmPool, cosmWasmPoolsParams, tokenOutDenom, takerFee) } diff --git a/router/usecase/pools/pool_factory.go b/router/usecase/pools/pool_factory.go index 1f341a876..12f024061 100644 --- a/router/usecase/pools/pool_factory.go +++ b/router/usecase/pools/pool_factory.go @@ -15,7 +15,7 @@ import ( // NewRoutablePool creates a new RoutablePool. // Panics if pool is of invalid type or if does not contain tick data when a concentrated pool. -func NewRoutablePool(pool sqsdomain.PoolI, tokenOutDenom string, takerFee osmomath.Dec, cosmWasmConfig domain.CosmWasmPoolRouterConfig, scalingFactorGetterCb domain.ScalingFactorGetterCb) (domain.RoutablePool, error) { +func NewRoutablePool(pool sqsdomain.PoolI, tokenOutDenom string, takerFee osmomath.Dec, cosmWasmPoolsParams CosmWasmPoolsParams) (domain.RoutablePool, error) { poolType := pool.GetType() chainPool := pool.GetUnderlyingPool() if poolType == poolmanagertypes.Concentrated { @@ -84,12 +84,12 @@ func NewRoutablePool(pool sqsdomain.PoolI, tokenOutDenom string, takerFee osmoma }, nil } - return newRoutableCosmWasmPool(pool, cosmWasmConfig, tokenOutDenom, takerFee, scalingFactorGetterCb) + return newRoutableCosmWasmPool(pool, tokenOutDenom, takerFee, cosmWasmPoolsParams) } // newRoutableCosmWasmPool creates a new RoutablePool for CosmWasm pools. // Panics if the given pool is not a cosmwasm pool or if the -func newRoutableCosmWasmPool(pool sqsdomain.PoolI, cosmWasmConfig domain.CosmWasmPoolRouterConfig, tokenOutDenom string, takerFee osmomath.Dec, scalingFactorGetterCb domain.ScalingFactorGetterCb) (domain.RoutablePool, error) { +func newRoutableCosmWasmPool(pool sqsdomain.PoolI, tokenOutDenom string, takerFee osmomath.Dec, cosmWasmPoolsParams CosmWasmPoolsParams) (domain.RoutablePool, error) { chainPool := pool.GetUnderlyingPool() poolType := pool.GetType() @@ -104,7 +104,7 @@ func newRoutableCosmWasmPool(pool sqsdomain.PoolI, cosmWasmConfig domain.CosmWas balances := pool.GetSQSPoolModel().Balances // Check if the pool is a transmuter pool - _, isTransmuter := cosmWasmConfig.TransmuterCodeIDs[cosmwasmPool.CodeId] + _, isTransmuter := cosmWasmPoolsParams.Config.TransmuterCodeIDs[cosmwasmPool.CodeId] if isTransmuter { spreadFactor := pool.GetSQSPoolModel().SpreadFactor @@ -118,21 +118,16 @@ func newRoutableCosmWasmPool(pool sqsdomain.PoolI, cosmWasmConfig domain.CosmWas }, nil } - _, isGeneralizedCosmWasmPool := cosmWasmConfig.GeneralCosmWasmCodeIDs[cosmwasmPool.CodeId] + _, isGeneralizedCosmWasmPool := cosmWasmPoolsParams.Config.GeneralCosmWasmCodeIDs[cosmwasmPool.CodeId] if isGeneralizedCosmWasmPool { - wasmClient, err := initializeWasmClient(cosmWasmConfig.ChainGRPCGatewayEndpoint) - if err != nil { - return nil, err - } - spreadFactor := pool.GetSQSPoolModel().SpreadFactor // for most other CosmWasm pools, interaction with the chain will // be required. As a result, we have a custom implementation. - return NewRoutableCosmWasmPool(cosmwasmPool, balances, tokenOutDenom, takerFee, spreadFactor, wasmClient, scalingFactorGetterCb), nil + return NewRoutableCosmWasmPool(cosmwasmPool, balances, tokenOutDenom, takerFee, spreadFactor, cosmWasmPoolsParams), nil } - return newRoutableCosmWasmPoolWithCustomModel(pool, cosmwasmPool, cosmWasmConfig, tokenOutDenom, takerFee) + return newRoutableCosmWasmPoolWithCustomModel(pool, cosmwasmPool, cosmWasmPoolsParams, tokenOutDenom, takerFee) } // newRoutableCosmWasmPoolWithCustomModel creates a new RoutablePool for CosmWasm pools that require a custom CosmWasmPoolModel. @@ -143,7 +138,7 @@ func newRoutableCosmWasmPool(pool sqsdomain.PoolI, cosmWasmConfig domain.CosmWas func newRoutableCosmWasmPoolWithCustomModel( pool sqsdomain.PoolI, cosmwasmPool *cwpoolmodel.CosmWasmPool, - cosmWasmConfig domain.CosmWasmPoolRouterConfig, + cosmWasmPoolsParams CosmWasmPoolsParams, tokenOutDenom string, takerFee osmomath.Dec, ) (domain.RoutablePool, error) { @@ -157,7 +152,7 @@ func newRoutableCosmWasmPoolWithCustomModel( // since v2, we introduce concept of alloyed assets but not yet actively used // since v3, we introduce concept of normalization factor // `routableAlloyTransmuterPoolImpl` is v3 compatible - _, isAlloyedTransmuterCodeId := cosmWasmConfig.AlloyedTransmuterCodeIDs[cosmwasmPool.CodeId] + _, isAlloyedTransmuterCodeId := cosmWasmPoolsParams.Config.AlloyedTransmuterCodeIDs[cosmwasmPool.CodeId] if isAlloyedTransmuterCodeId && model.IsAlloyTransmuter() { if model.Data.AlloyTransmuter == nil { return nil, domain.CosmWasmPoolDataMissingError{ @@ -176,7 +171,7 @@ func newRoutableCosmWasmPoolWithCustomModel( }, nil } - _, isOrderbookCodeId := cosmWasmConfig.OrderbookCodeIDs[cosmwasmPool.CodeId] + _, isOrderbookCodeId := cosmWasmPoolsParams.Config.OrderbookCodeIDs[cosmwasmPool.CodeId] if isOrderbookCodeId && model.IsOrderbook() { if model.Data.Orderbook == nil { return nil, domain.CosmWasmPoolDataMissingError{ diff --git a/router/usecase/pools/pool_factory_test.go b/router/usecase/pools/pool_factory_test.go index 58be77319..068756b21 100644 --- a/router/usecase/pools/pool_factory_test.go +++ b/router/usecase/pools/pool_factory_test.go @@ -190,7 +190,10 @@ func TestNewRoutableCosmWasmPoolWithCustomModel(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - routablePool, err := pools.NewRoutableCosmWasmPoolWithCustomModel(tt.pool, tt.cosmwasmPool, tt.cosmWasmConfig, tt.tokenOutDenom, tt.takerFee) + cosmWasmPoolsParams := pools.CosmWasmPoolsParams{ + Config: tt.cosmWasmConfig, + } + routablePool, err := pools.NewRoutableCosmWasmPoolWithCustomModel(tt.pool, tt.cosmwasmPool, cosmWasmPoolsParams, tt.tokenOutDenom, tt.takerFee) if tt.expectedError != nil { require.Equal(t, tt.expectedError, err) diff --git a/router/usecase/pools/routable_concentrated_pool_test.go b/router/usecase/pools/routable_concentrated_pool_test.go index 449068fd5..06162df16 100644 --- a/router/usecase/pools/routable_concentrated_pool_test.go +++ b/router/usecase/pools/routable_concentrated_pool_test.go @@ -88,7 +88,10 @@ func (s *RoutablePoolTestSuite) TestCalculateTokenOutByTokenIn_Concentrated_Succ PoolDenoms: []string{"foo", "bar"}, }, } - routablePool, err := pools.NewRoutablePool(poolWrapper, tc.TokenOutDenom, noTakerFee, domain.CosmWasmPoolRouterConfig{}, domain.UnsetScalingFactorGetterCb) + cosmWasmPoolsParams := pools.CosmWasmPoolsParams{ + ScalingFactorGetterCb: domain.UnsetScalingFactorGetterCb, + } + routablePool, err := pools.NewRoutablePool(poolWrapper, tc.TokenOutDenom, noTakerFee, cosmWasmPoolsParams) s.Require().NoError(err) tokenOut, err := routablePool.CalculateTokenOutByTokenIn(context.TODO(), tc.TokenIn) diff --git a/router/usecase/pools/routable_cw_alloy_transmuter_pool_test.go b/router/usecase/pools/routable_cw_alloy_transmuter_pool_test.go index b85eccb5e..ff775690a 100644 --- a/router/usecase/pools/routable_cw_alloy_transmuter_pool_test.go +++ b/router/usecase/pools/routable_cw_alloy_transmuter_pool_test.go @@ -49,11 +49,15 @@ func (s *RoutablePoolTestSuite) SetupRoutableAlloyTransmuterPool(tokenInDenom, t TakerFee: takerFee, } - routablePool, err := pools.NewRoutablePool(mock, tokenOutDenom, takerFee, domain.CosmWasmPoolRouterConfig{ - AlloyedTransmuterCodeIDs: map[uint64]struct{}{ - defaultPoolID: {}, + cosmWasmPoolsParams := pools.CosmWasmPoolsParams{ + Config: domain.CosmWasmPoolRouterConfig{ + AlloyedTransmuterCodeIDs: map[uint64]struct{}{ + defaultPoolID: {}, + }, }, - }, domain.UnsetScalingFactorGetterCb) + ScalingFactorGetterCb: domain.UnsetScalingFactorGetterCb, + } + routablePool, err := pools.NewRoutablePool(mock, tokenOutDenom, takerFee, cosmWasmPoolsParams) s.Require().NoError(err) return routablePool diff --git a/router/usecase/pools/routable_cw_orderbook_pool_test.go b/router/usecase/pools/routable_cw_orderbook_pool_test.go index 2acad1f31..0fc1670c1 100644 --- a/router/usecase/pools/routable_cw_orderbook_pool_test.go +++ b/router/usecase/pools/routable_cw_orderbook_pool_test.go @@ -62,11 +62,15 @@ func (s *RoutablePoolTestSuite) SetupRoutableOrderbookPool( TakerFee: takerFee, } - routablePool, err := pools.NewRoutablePool(mock, tokenOutDenom, takerFee, domain.CosmWasmPoolRouterConfig{ - OrderbookCodeIDs: map[uint64]struct{}{ - cosmwasmPool.GetId(): {}, + cosmWasmPoolsParams := pools.CosmWasmPoolsParams{ + Config: domain.CosmWasmPoolRouterConfig{ + OrderbookCodeIDs: map[uint64]struct{}{ + cosmwasmPool.GetId(): {}, + }, }, - }, domain.UnsetScalingFactorGetterCb) + ScalingFactorGetterCb: domain.UnsetScalingFactorGetterCb, + } + routablePool, err := pools.NewRoutablePool(mock, tokenOutDenom, takerFee, cosmWasmPoolsParams) s.Require().NoError(err) return routablePool diff --git a/router/usecase/pools/routable_cw_pool.go b/router/usecase/pools/routable_cw_pool.go index 921a46381..a634143f4 100644 --- a/router/usecase/pools/routable_cw_pool.go +++ b/router/usecase/pools/routable_cw_pool.go @@ -38,7 +38,7 @@ type routableCosmWasmPoolImpl struct { } // NewRoutableCosmWasmPool returns a new routable cosmwasm pool with the given parameters. -func NewRoutableCosmWasmPool(pool *cwpoolmodel.CosmWasmPool, balances sdk.Coins, tokenOutDenom string, takerFee osmomath.Dec, spreadFactor osmomath.Dec, wasmClient wasmtypes.QueryClient, scalingFactorGetterCb domain.ScalingFactorGetterCb) domain.RoutablePool { +func NewRoutableCosmWasmPool(pool *cwpoolmodel.CosmWasmPool, balances sdk.Coins, tokenOutDenom string, takerFee osmomath.Dec, spreadFactor osmomath.Dec, cosmWasmPoolsParams CosmWasmPoolsParams) domain.RoutablePool { // Initializa routable cosmwasm pool routableCosmWasmPool := &routableCosmWasmPoolImpl{ ChainPool: pool, @@ -46,7 +46,7 @@ func NewRoutableCosmWasmPool(pool *cwpoolmodel.CosmWasmPool, balances sdk.Coins, TokenOutDenom: tokenOutDenom, TakerFee: takerFee, SpreadFactor: spreadFactor, - wasmClient: wasmClient, + wasmClient: cosmWasmPoolsParams.WasmClient, // Note, that there is no calculator set // since we need to wire quote calculation callback to it. @@ -54,7 +54,7 @@ func NewRoutableCosmWasmPool(pool *cwpoolmodel.CosmWasmPool, balances sdk.Coins, } // Initialize spot price calculator. - spotPriceCalculator := NewSpotPriceQuoteComputer(scalingFactorGetterCb, routableCosmWasmPool.calculateTokenOutByTokenIn) + spotPriceCalculator := NewSpotPriceQuoteComputer(cosmWasmPoolsParams.ScalingFactorGetterCb, routableCosmWasmPool.calculateTokenOutByTokenIn) // Set it on the routable cosmwasm pool. routableCosmWasmPool.spotPriceQuoteCalculator = spotPriceCalculator diff --git a/router/usecase/pools/routable_cw_transmuter_pool_test.go b/router/usecase/pools/routable_cw_transmuter_pool_test.go index 56940ebae..60efac7dd 100644 --- a/router/usecase/pools/routable_cw_transmuter_pool_test.go +++ b/router/usecase/pools/routable_cw_transmuter_pool_test.go @@ -60,11 +60,16 @@ func (s *RoutablePoolTestSuite) TestCalculateTokenOutByTokenIn_Transmuter() { poolType := cosmwasmPool.GetType() mock := &mocks.MockRoutablePool{ChainPoolModel: cosmwasmPool.AsSerializablePool(), Balances: tc.balances, PoolType: poolType} - routablePool, err := pools.NewRoutablePool(mock, tc.tokenOutDenom, noTakerFee, domain.CosmWasmPoolRouterConfig{ - TransmuterCodeIDs: map[uint64]struct{}{ - cosmwasmPool.GetCodeId(): {}, + + cosmWasmPoolsParams := pools.CosmWasmPoolsParams{ + Config: domain.CosmWasmPoolRouterConfig{ + TransmuterCodeIDs: map[uint64]struct{}{ + cosmwasmPool.GetCodeId(): {}, + }, }, - }, domain.UnsetScalingFactorGetterCb) + ScalingFactorGetterCb: domain.UnsetScalingFactorGetterCb, + } + routablePool, err := pools.NewRoutablePool(mock, tc.tokenOutDenom, noTakerFee, cosmWasmPoolsParams) s.Require().NoError(err) // Overwrite pool type for edge case testing diff --git a/router/usecase/pools/routable_pool_test.go b/router/usecase/pools/routable_pool_test.go index 9879c4434..840ec0462 100644 --- a/router/usecase/pools/routable_pool_test.go +++ b/router/usecase/pools/routable_pool_test.go @@ -94,7 +94,10 @@ func (s *RoutablePoolTestSuite) TestCalculateTokenOutByTokenIn_CFMM() { s.Require().NoError(err) mock := &mocks.MockRoutablePool{ChainPoolModel: pool, PoolType: tc.poolType} - routablePool, err := pools.NewRoutablePool(mock, tc.tokenOutDenom, noTakerFee, domain.CosmWasmPoolRouterConfig{}, domain.UnsetScalingFactorGetterCb) + cosmWasmPoolsParams := pools.CosmWasmPoolsParams{ + ScalingFactorGetterCb: domain.UnsetScalingFactorGetterCb, + } + routablePool, err := pools.NewRoutablePool(mock, tc.tokenOutDenom, noTakerFee, cosmWasmPoolsParams) s.Require().NoError(err) tokenOut, err := routablePool.CalculateTokenOutByTokenIn(context.TODO(), tc.tokenIn) diff --git a/router/usecase/quote_test.go b/router/usecase/quote_test.go index 596938bee..60241e66b 100644 --- a/router/usecase/quote_test.go +++ b/router/usecase/quote_test.go @@ -336,7 +336,11 @@ func (s *RouterTestSuite) validateRoutes(expectedRoutes []domain.SplitRoute, act } func (s *RouterTestSuite) newRoutablePool(pool sqsdomain.PoolI, tokenOutDenom string, takerFee osmomath.Dec, cosmWasmConfig domain.CosmWasmPoolRouterConfig) domain.RoutablePool { - routablePool, err := pools.NewRoutablePool(pool, tokenOutDenom, takerFee, cosmWasmConfig, domain.UnsetScalingFactorGetterCb) + cosmWasmPoolsParams := pools.CosmWasmPoolsParams{ + Config: cosmWasmConfig, + ScalingFactorGetterCb: domain.UnsetScalingFactorGetterCb, + } + routablePool, err := pools.NewRoutablePool(pool, tokenOutDenom, takerFee, cosmWasmPoolsParams) s.Require().NoError(err) return routablePool } diff --git a/router/usecase/router_usecase_test.go b/router/usecase/router_usecase_test.go index 1f6cd8d29..a2384e839 100644 --- a/router/usecase/router_usecase_test.go +++ b/router/usecase/router_usecase_test.go @@ -969,7 +969,8 @@ func (s *RouterTestSuite) TestGetCustomQuote_GetCustomDirectQuotes_Mainnet_UOSMO routerRepositoryMock.SetTakerFees(mainnetState.TakerFeeMap) // Setup pools usecase mock. - poolsUsecase := poolsusecase.NewPoolsUsecase(&domain.PoolsConfig{}, "node-uri-placeholder", routerRepositoryMock, domain.UnsetScalingFactorGetterCb, &log.NoOpLogger{}) + poolsUsecase, err := poolsusecase.NewPoolsUsecase(&domain.PoolsConfig{}, "node-uri-placeholder", routerRepositoryMock, domain.UnsetScalingFactorGetterCb, &log.NoOpLogger{}) + s.Require().NoError(err) poolsUsecase.StorePools(mainnetState.Pools) tokenMetaDataHolder := mocks.TokenMetadataHolderMock{} diff --git a/router/usecase/routertesting/suite.go b/router/usecase/routertesting/suite.go index 15ad313f6..abcbe5b31 100644 --- a/router/usecase/routertesting/suite.go +++ b/router/usecase/routertesting/suite.go @@ -387,7 +387,8 @@ func (s *RouterTestHelper) SetupRouterAndPoolsUsecase(mainnetState MockMainnetSt routerRepositoryMock.SetCandidateRouteSearchData(mainnetState.CandidateRouteSearchData) // Setup pools usecase mock. - poolsUsecase := poolsusecase.NewPoolsUsecase(&options.PoolsConfig, "node-uri-placeholder", routerRepositoryMock, domain.UnsetScalingFactorGetterCb, &log.NoOpLogger{}) + poolsUsecase, err := poolsusecase.NewPoolsUsecase(&options.PoolsConfig, "node-uri-placeholder", routerRepositoryMock, domain.UnsetScalingFactorGetterCb, &log.NoOpLogger{}) + s.Require().NoError(err) err = poolsUsecase.StorePools(mainnetState.Pools) s.Require().NoError(err)