From 4851e94eba12e6cb57cdf6ead9ee60cec3934caa Mon Sep 17 00:00:00 2001 From: Ryan O'Hara-Reid Date: Thu, 26 Aug 2021 13:09:14 +1000 Subject: [PATCH] Engine/ExchangeManager: Return error for method GetExchangeByName (#760) * engine: Add error returns * engine: after merge fixes * engine: remove interface * linter: fix shadow declarations * engine: fix tests * niterinos: fixed * GLORIOUS NITS! --- backtester/backtest/backtest.go | 13 +- engine/apiserver.go | 13 +- engine/datahistory_manager.go | 24 +- engine/engine.go | 2 +- engine/engine_test.go | 34 +-- engine/event_manager.go | 3 +- engine/exchange_manager.go | 20 +- engine/exchange_manager_test.go | 6 +- engine/helpers.go | 18 +- engine/helpers_test.go | 6 +- engine/order_manager.go | 41 ++- engine/order_manager_test.go | 7 +- engine/rpcserver.go | 279 ++++++++++++------ engine/rpcserver_test.go | 75 +++-- engine/subsystem_types.go | 10 +- engine/withdraw_manager.go | 25 +- gctscript/wrappers/gct/exchange/exchange.go | 8 +- .../wrappers/gct/exchange/exchange_test.go | 12 +- 18 files changed, 360 insertions(+), 236 deletions(-) diff --git a/backtester/backtest/backtest.go b/backtester/backtest/backtest.go index 6c0e0536c09..e19be682a7b 100644 --- a/backtester/backtest/backtest.go +++ b/backtester/backtest/backtest.go @@ -135,7 +135,11 @@ func NewFromConfig(cfg *config.Config, templatePath, output string, bot *engine. cfg.CurrencySettings[i].Base+cfg.CurrencySettings[i].Quote, err) } - exch := bot.ExchangeManager.GetExchangeByName(cfg.CurrencySettings[i].ExchangeName) + var exch gctexchange.IBotExchange + exch, err = bot.ExchangeManager.GetExchangeByName(cfg.CurrencySettings[i].ExchangeName) + if err != nil { + return nil, fmt.Errorf("could not get exchange by name %w", err) + } b := exch.GetBase() var pFmt currency.PairFormat pFmt, err = b.GetPairFormat(a, true) @@ -332,10 +336,9 @@ func (bt *BackTest) setupExchangeSettings(cfg *config.Config) (exchange.Exchange } func (bt *BackTest) loadExchangePairAssetBase(exch, base, quote, ass string) (gctexchange.IBotExchange, currency.Pair, asset.Item, error) { - var err error - e := bt.Bot.GetExchangeByName(exch) - if e == nil { - return nil, currency.Pair{}, "", engine.ErrExchangeNotFound + e, err := bt.Bot.GetExchangeByName(exch) + if err != nil { + return nil, currency.Pair{}, "", err } var cp, fPair currency.Pair diff --git a/engine/apiserver.go b/engine/apiserver.go index 0bee8f68919..e7c95feaf50 100644 --- a/engine/apiserver.go +++ b/engine/apiserver.go @@ -19,7 +19,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/config" "github.com/thrasher-corp/gocryptotrader/currency" - "github.com/thrasher-corp/gocryptotrader/database/repository/exchange" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/log" ) @@ -805,9 +804,9 @@ func wsGetTicker(client *websocketClient, data interface{}) error { return err } - exch := client.exchangeManager.GetExchangeByName(tickerReq.Exchange) - if exch == nil { - wsResp.Error = exchange.ErrNoExchangeFound.Error() + exch, err := client.exchangeManager.GetExchangeByName(tickerReq.Exchange) + if err != nil { + wsResp.Error = err.Error() sendErr := client.SendWebsocketMessage(wsResp) if sendErr != nil { log.Error(log.APIServerMgr, sendErr) @@ -860,9 +859,9 @@ func wsGetOrderbook(client *websocketClient, data interface{}) error { return err } - exch := client.exchangeManager.GetExchangeByName(orderbookReq.Exchange) - if exch == nil { - wsResp.Error = exchange.ErrNoExchangeFound.Error() + exch, err := client.exchangeManager.GetExchangeByName(orderbookReq.Exchange) + if err != nil { + wsResp.Error = err.Error() sendErr := client.SendWebsocketMessage(wsResp) if sendErr != nil { log.Error(log.APIServerMgr, sendErr) diff --git a/engine/datahistory_manager.go b/engine/datahistory_manager.go index 7597cb2fb20..cd0e087d300 100644 --- a/engine/datahistory_manager.go +++ b/engine/datahistory_manager.go @@ -302,11 +302,10 @@ func (m *DataHistoryManager) runJob(job *DataHistoryJob) error { if job.DataType == dataHistoryCandleValidationSecondarySourceType { exchangeName = job.SecondaryExchangeSource } - exch := m.exchangeManager.GetExchangeByName(exchangeName) - if exch == nil { - return fmt.Errorf("%s %w, cannot process job %s for %s %s", - job.Exchange, - errExchangeNotLoaded, + exch, err := m.exchangeManager.GetExchangeByName(exchangeName) + if err != nil { + return fmt.Errorf("%w, cannot process job %s for %s %s", + err, job.Nickname, job.Asset, job.Pair) @@ -314,19 +313,19 @@ func (m *DataHistoryManager) runJob(job *DataHistoryJob) error { if job.DataType == dataHistoryCandleValidationDataType || job.DataType == dataHistoryCandleValidationSecondarySourceType { - err := m.runValidationJob(job, exch) + err = m.runValidationJob(job, exch) if err != nil { return err } } else { - err := m.runDataJob(job, exch) + err = m.runDataJob(job, exch) if err != nil { return err } } dbJob := m.convertJobToDBModel(job) - err := m.jobDB.Upsert(dbJob) + err = m.jobDB.Upsert(dbJob) if err != nil { return fmt.Errorf("job %s failed to update database: %w", job.Nickname, err) } @@ -1172,12 +1171,9 @@ func (m *DataHistoryManager) validateJob(job *DataHistoryJob) error { return fmt.Errorf("job %s %w, exchange name required to lookup existing results", job.Nickname, errExchangeNameUnset) } } - exch := m.exchangeManager.GetExchangeByName(exchangeName) - if exch == nil { - return fmt.Errorf("job %s cannot process job: %s %w", - job.Nickname, - job.Exchange, - errExchangeNotLoaded) + exch, err := m.exchangeManager.GetExchangeByName(exchangeName) + if err != nil { + return fmt.Errorf("job %s cannot process job: %v", job.Nickname, err) } pairs, err := exch.GetEnabledPairs(job.Asset) if err != nil { diff --git a/engine/engine.go b/engine/engine.go index 1e83f4a67fa..81b52484400 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -681,7 +681,7 @@ func (bot *Engine) Stop() { } // GetExchangeByName returns an exchange given an exchange name -func (bot *Engine) GetExchangeByName(exchName string) exchange.IBotExchange { +func (bot *Engine) GetExchangeByName(exchName string) (exchange.IBotExchange, error) { return bot.ExchangeManager.GetExchangeByName(exchName) } diff --git a/engine/engine_test.go b/engine/engine_test.go index fa5d5e0065e..c1962bb16a7 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -165,27 +165,13 @@ func TestStartStopTwoDoesNotCausePanic(t *testing.T) { botTwo.Stop() } -func TestCheckExchangeExists(t *testing.T) { +func TestGetExchangeByName(t *testing.T) { t.Parallel() - em := SetupExchangeManager() - exch, err := em.NewExchangeByName(testExchange) - if !errors.Is(err, nil) { - t.Fatalf("received '%v' expected '%v'", err, nil) - } - exch.SetDefaults() - em.Add(exch) - e := &Engine{ExchangeManager: em} - if e.GetExchangeByName(testExchange) == nil { - t.Errorf("TestGetExchangeExists: Unable to find exchange") + _, err := (*ExchangeManager)(nil).GetExchangeByName("tehehe") + if !errors.Is(err, ErrNilSubsystem) { + t.Errorf("received: %v expected: %v", err, ErrNilSubsystem) } - if e.GetExchangeByName("Asdsad") != nil { - t.Errorf("TestGetExchangeExists: Non-existent exchange found") - } -} - -func TestGetExchangeByName(t *testing.T) { - t.Parallel() em := SetupExchangeManager() exch, err := em.NewExchangeByName(testExchange) if !errors.Is(err, nil) { @@ -201,18 +187,20 @@ func TestGetExchangeByName(t *testing.T) { } exch.SetEnabled(false) - bfx := e.GetExchangeByName(testExchange) + bfx, err := e.GetExchangeByName(testExchange) + if err != nil { + t.Fatal(err) + } if bfx.IsEnabled() { t.Errorf("TestGetExchangeByName: Unexpected result") } - if exch.GetName() != testExchange { t.Errorf("TestGetExchangeByName: Unexpected result") } - exch = e.GetExchangeByName("Asdasd") - if exch != nil { - t.Errorf("TestGetExchangeByName: Non-existent exchange found") + _, err = e.GetExchangeByName("Asdasd") + if !errors.Is(err, ErrExchangeNotFound) { + t.Errorf("received: %v expected: %v", err, ErrExchangeNotFound) } } diff --git a/engine/event_manager.go b/engine/event_manager.go index a328aafcd08..0a12cc04951 100644 --- a/engine/event_manager.go +++ b/engine/event_manager.go @@ -234,7 +234,8 @@ func (m *eventManager) isValidEvent(exchange, item string, condition EventCondit // isValidExchange validates the exchange func (m *eventManager) isValidExchange(exchangeName string) bool { - return m.exchangeManager.GetExchangeByName(exchangeName) != nil + _, err := m.exchangeManager.GetExchangeByName(exchangeName) + return err == nil } // isValidCondition validates passed in condition diff --git a/engine/exchange_manager.go b/engine/exchange_manager.go index 8cb00d94e24..1386a117cf2 100644 --- a/engine/exchange_manager.go +++ b/engine/exchange_manager.go @@ -43,6 +43,7 @@ var ( ErrExchangeNotFound = errors.New("exchange not found") ErrExchangeAlreadyLoaded = errors.New("exchange already loaded") ErrExchangeFailedToLoad = errors.New("exchange failed to load") + errExchangeNameIsEmpty = errors.New("exchange name is empty") ) // CustomExchangeBuilder interface allows external applications to create @@ -91,9 +92,9 @@ func (m *ExchangeManager) RemoveExchange(exchName string) error { if m.Len() == 0 { return ErrNoExchangesLoaded } - exch := m.GetExchangeByName(exchName) - if exch == nil { - return ErrExchangeNotFound + _, err := m.GetExchangeByName(exchName) + if err != nil { + return err } m.m.Lock() defer m.m.Unlock() @@ -103,17 +104,20 @@ func (m *ExchangeManager) RemoveExchange(exchName string) error { } // GetExchangeByName returns an exchange by its name if it exists -func (m *ExchangeManager) GetExchangeByName(exchangeName string) exchange.IBotExchange { +func (m *ExchangeManager) GetExchangeByName(exchangeName string) (exchange.IBotExchange, error) { if m == nil { - return nil + return nil, fmt.Errorf("exchange manager: %w", ErrNilSubsystem) + } + if exchangeName == "" { + return nil, fmt.Errorf("exchange manager: %w", errExchangeNameIsEmpty) } m.m.Lock() defer m.m.Unlock() exch, ok := m.exchanges[strings.ToLower(exchangeName)] if !ok { - return nil + return nil, fmt.Errorf("%s %w", exchangeName, ErrExchangeNotFound) } - return exch + return exch, nil } // Len says how many exchanges are loaded @@ -129,7 +133,7 @@ func (m *ExchangeManager) NewExchangeByName(name string) (exchange.IBotExchange, return nil, fmt.Errorf("exchange manager %w", ErrNilSubsystem) } nameLower := strings.ToLower(name) - if m.GetExchangeByName(nameLower) != nil { + if exch, _ := m.GetExchangeByName(nameLower); exch != nil { return nil, fmt.Errorf("%s %w", name, ErrExchangeAlreadyLoaded) } var exch exchange.IBotExchange diff --git a/engine/exchange_manager_test.go b/engine/exchange_manager_test.go index 9dcad950ef9..b951f441a1a 100644 --- a/engine/exchange_manager_test.go +++ b/engine/exchange_manager_test.go @@ -1,6 +1,7 @@ package engine import ( + "errors" "fmt" "strings" "testing" @@ -55,8 +56,9 @@ func TestExchangeManagerRemoveExchange(t *testing.T) { b := new(bitfinex.Bitfinex) b.SetDefaults() m.Add(b) - if err := m.RemoveExchange("Bitstamp"); err != ErrExchangeNotFound { - t.Error("Bitstamp exchange should return an error") + err := m.RemoveExchange("Bitstamp") + if !errors.Is(err, ErrExchangeNotFound) { + t.Errorf("received: %v but expected: %v", err, ErrExchangeNotFound) } if err := m.RemoveExchange("BiTFiNeX"); err != nil { t.Error("exchange should have been removed") diff --git a/engine/helpers.go b/engine/helpers.go index 18b249924b2..0607a8bb2a7 100644 --- a/engine/helpers.go +++ b/engine/helpers.go @@ -531,9 +531,9 @@ func GetRelatableCurrencies(p currency.Pair, incOrig, incUSDT bool) currency.Pai // GetSpecificOrderbook returns a specific orderbook given the currency, // exchangeName and assetType func (bot *Engine) GetSpecificOrderbook(p currency.Pair, exchangeName string, assetType asset.Item) (*orderbook.Base, error) { - exch := bot.GetExchangeByName(exchangeName) - if exch == nil { - return nil, ErrExchangeNotFound + exch, err := bot.GetExchangeByName(exchangeName) + if err != nil { + return nil, err } return exch.FetchOrderbook(p, assetType) } @@ -541,9 +541,9 @@ func (bot *Engine) GetSpecificOrderbook(p currency.Pair, exchangeName string, as // GetSpecificTicker returns a specific ticker given the currency, // exchangeName and assetType func (bot *Engine) GetSpecificTicker(p currency.Pair, exchangeName string, assetType asset.Item) (*ticker.Price, error) { - exch := bot.GetExchangeByName(exchangeName) - if exch == nil { - return nil, ErrExchangeNotFound + exch, err := bot.GetExchangeByName(exchangeName) + if err != nil { + return nil, err } return exch.FetchTicker(p, assetType) } @@ -661,9 +661,9 @@ func (bot *Engine) GetExchangeCryptocurrencyDepositAddress(exchName, accountID s return bot.DepositAddressManager.GetDepositAddressByExchangeAndCurrency(exchName, item) } - exch := bot.GetExchangeByName(exchName) - if exch == nil { - return "", ErrExchangeNotFound + exch, err := bot.GetExchangeByName(exchName) + if err != nil { + return "", err } return exch.GetDepositAddress(item, accountID) } diff --git a/engine/helpers_test.go b/engine/helpers_test.go index 34047372a8b..6dfcc58a65f 100644 --- a/engine/helpers_test.go +++ b/engine/helpers_test.go @@ -162,7 +162,11 @@ func TestGetAuthAPISupportedExchanges(t *testing.T) { t.Fatal("Unexpected result", result) } - exch := e.ExchangeManager.GetExchangeByName(testExchange) + exch, err := e.ExchangeManager.GetExchangeByName(testExchange) + if err != nil { + t.Fatal(err) + } + b := exch.GetBase() b.API.AuthenticatedWebsocketSupport = true b.API.Credentials.Key = "test" diff --git a/engine/order_manager.go b/engine/order_manager.go index d3f6e8441e8..af2696a7c58 100644 --- a/engine/order_manager.go +++ b/engine/order_manager.go @@ -180,9 +180,8 @@ func (m *OrderManager) Cancel(cancel *order.Cancel) error { return err } - exch := m.orderStore.exchangeManager.GetExchangeByName(cancel.Exchange) - if exch == nil { - err = ErrExchangeNotFound + exch, err := m.orderStore.exchangeManager.GetExchangeByName(cancel.Exchange) + if err != nil { return err } @@ -232,9 +231,9 @@ func (m *OrderManager) GetOrderInfo(exchangeName, orderID string, cp currency.Pa return order.Detail{}, ErrOrderIDCannotBeEmpty } - exch := m.orderStore.exchangeManager.GetExchangeByName(exchangeName) - if exch == nil { - return order.Detail{}, ErrExchangeNotFound + exch, err := m.orderStore.exchangeManager.GetExchangeByName(exchangeName) + if err != nil { + return order.Detail{}, err } result, err := exch.GetOrderInfo(orderID, cp, a) if err != nil { @@ -317,9 +316,9 @@ func (m *OrderManager) Modify(mod *order.Modify) (*order.ModifyResponse, error) } // Get exchange instance and submit order modification request. - exch := m.orderStore.exchangeManager.GetExchangeByName(mod.Exchange) - if exch == nil { - return nil, ErrExchangeNotFound + exch, err := m.orderStore.exchangeManager.GetExchangeByName(mod.Exchange) + if err != nil { + return nil, err } res, err := exch.ModifyOrder(mod) if err != nil { @@ -369,9 +368,9 @@ func (m *OrderManager) Submit(newOrder *order.Submit) (*OrderSubmitResponse, err if err != nil { return nil, err } - exch := m.orderStore.exchangeManager.GetExchangeByName(newOrder.Exchange) - if exch == nil { - return nil, ErrExchangeNotFound + exch, err := m.orderStore.exchangeManager.GetExchangeByName(newOrder.Exchange) + if err != nil { + return nil, err } // Checks for exchange min max limits for order amounts before order @@ -409,9 +408,9 @@ func (m *OrderManager) SubmitFakeOrder(newOrder *order.Submit, resultingOrder or if err != nil { return nil, err } - exch := m.orderStore.exchangeManager.GetExchangeByName(newOrder.Exchange) - if exch == nil { - return nil, ErrExchangeNotFound + exch, err := m.orderStore.exchangeManager.GetExchangeByName(newOrder.Exchange) + if err != nil { + return nil, err } if checkExchangeLimits { @@ -746,9 +745,9 @@ func (s *store) modifyExisting(id string, mod *order.Modify) error { // order exists and updates/creates it. func (s *store) upsert(od *order.Detail) error { lName := strings.ToLower(od.Exchange) - exch := s.exchangeManager.GetExchangeByName(lName) - if exch == nil { - return ErrExchangeNotFound + _, err := s.exchangeManager.GetExchangeByName(lName) + if err != nil { + return err } s.m.Lock() defer s.m.Unlock() @@ -818,9 +817,9 @@ func (s *store) add(det *order.Detail) error { if det == nil { return errors.New("order store: Order is nil") } - exch := s.exchangeManager.GetExchangeByName(det.Exchange) - if exch == nil { - return ErrExchangeNotFound + _, err := s.exchangeManager.GetExchangeByName(det.Exchange) + if err != nil { + return err } if s.exists(det) { return ErrOrdersAlreadyExists diff --git a/engine/order_manager_test.go b/engine/order_manager_test.go index 63ea95e9247..26fb525c146 100644 --- a/engine/order_manager_test.go +++ b/engine/order_manager_test.go @@ -503,12 +503,17 @@ func TestCancelAllOrders(t *testing.T) { if err != nil { t.Error(err) } - exch := m.orderStore.exchangeManager.GetExchangeByName(testExchange) + m.CancelAllOrders([]exchange.IBotExchange{}) if o.Status == order.Cancelled { t.Error("Order should not be cancelled") } + exch, err := m.orderStore.exchangeManager.GetExchangeByName(testExchange) + if err != nil { + t.Fatal(err) + } + m.CancelAllOrders([]exchange.IBotExchange{exch}) if o.Status != order.Cancelled { t.Error("Order should be cancelled") diff --git a/engine/rpcserver.go b/engine/rpcserver.go index 3f7c75bb741..ab86fffd72d 100644 --- a/engine/rpcserver.go +++ b/engine/rpcserver.go @@ -52,6 +52,7 @@ import ( var ( errExchangeNotLoaded = errors.New("exchange is not loaded/doesn't exist") + errExchangeNotEnabled = errors.New("exchange is not enabled") errExchangeBaseNotFound = errors.New("cannot get exchange base") errInvalidArguments = errors.New("invalid arguments received") errExchangeNameUnset = errors.New("exchange name unset") @@ -92,10 +93,13 @@ func (s *RPCServer) authenticateClient(ctx context.Context) (context.Context, er return ctx, fmt.Errorf("unable to base64 decode authorization header") } - username := strings.Split(string(decoded), ":")[0] - password := strings.Split(string(decoded), ":")[1] + credentials := strings.Split(string(decoded), ":") - if username != s.Config.RemoteControl.Username || password != s.Config.RemoteControl.Password { + username := credentials[0] + password := credentials[1] + + if username != s.Config.RemoteControl.Username || + password != s.Config.RemoteControl.Password { return ctx, fmt.Errorf("username/password mismatch") } @@ -286,8 +290,8 @@ func (s *RPCServer) EnableExchange(_ context.Context, r *gctrpc.GenericExchangeN // GetExchangeOTPCode retrieves an exchanges OTP code func (s *RPCServer) GetExchangeOTPCode(_ context.Context, r *gctrpc.GenericExchangeNameRequest) (*gctrpc.GetExchangeOTPResponse, error) { - if exch := s.GetExchangeByName(r.Exchange); exch == nil { - return nil, ErrExchangeNotFound + if _, err := s.GetExchangeByName(r.Exchange); err != nil { + return nil, err } result, err := s.GetExchangeOTPByName(r.Exchange) return &gctrpc.GetExchangeOTPResponse{OtpCode: result}, err @@ -342,7 +346,11 @@ func (s *RPCServer) GetTicker(_ context.Context, r *gctrpc.GetTickerRequest) (*g return nil, err } - e := s.GetExchangeByName(r.Exchange) + e, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, e, a, currency.Pair{ Delimiter: r.Pair.Delimiter, Base: currency.NewCode(r.Pair.Base), @@ -537,7 +545,10 @@ func (s *RPCServer) GetAccountInfo(_ context.Context, r *gctrpc.GetAccountInfoRe return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } err = checkParams(r.Exchange, exch, assetType, currency.Pair{}) if err != nil { @@ -559,7 +570,11 @@ func (s *RPCServer) UpdateAccountInfo(_ context.Context, r *gctrpc.GetAccountInf return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, assetType, currency.Pair{}) if err != nil { return nil, err @@ -598,7 +613,11 @@ func (s *RPCServer) GetAccountInfoStream(r *gctrpc.GetAccountInfoRequest, stream return err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return err + } + err = checkParams(r.Exchange, exch, assetType, currency.Pair{}) if err != nil { return err @@ -858,7 +877,12 @@ func (s *RPCServer) GetOrders(_ context.Context, r *gctrpc.GetOrdersRequest) (*g r.Pair.Base, r.Pair.Quote, r.Pair.Delimiter) - exch := s.GetExchangeByName(r.Exchange) + + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, cp) if err != nil { return nil, err @@ -966,7 +990,12 @@ func (s *RPCServer) GetManagedOrders(_ context.Context, r *gctrpc.GetOrdersReque r.Pair.Base, r.Pair.Quote, r.Pair.Delimiter) - exch := s.GetExchangeByName(r.Exchange) + + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, cp) if err != nil { return nil, err @@ -1052,7 +1081,11 @@ func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gct return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, pair) if err != nil { return nil, err @@ -1124,7 +1157,11 @@ func (s *RPCServer) SubmitOrder(_ context.Context, r *gctrpc.SubmitOrderRequest) Quote: currency.NewCode(r.Pair.Quote), } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, p) if err != nil { return nil, err @@ -1177,8 +1214,12 @@ func (s *RPCServer) SimulateOrder(_ context.Context, r *gctrpc.SimulateOrderRequ Quote: currency.NewCode(r.Pair.Quote), } - exch := s.GetExchangeByName(r.Exchange) - err := checkParams(r.Exchange, exch, asset.Spot, p) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + + err = checkParams(r.Exchange, exch, asset.Spot, p) if err != nil { return nil, err } @@ -1224,8 +1265,12 @@ func (s *RPCServer) WhaleBomb(_ context.Context, r *gctrpc.WhaleBombRequest) (*g Quote: currency.NewCode(r.Pair.Quote), } - exch := s.GetExchangeByName(r.Exchange) - err := checkParams(r.Exchange, exch, asset.Spot, p) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + + err = checkParams(r.Exchange, exch, asset.Spot, p) if err != nil { return nil, err } @@ -1279,7 +1324,11 @@ func (s *RPCServer) CancelOrder(_ context.Context, r *gctrpc.CancelOrderRequest) return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, p) if err != nil { return nil, err @@ -1314,7 +1363,11 @@ func (s *RPCServer) CancelBatchOrders(_ context.Context, r *gctrpc.CancelBatchOr return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, assetType, pair) if err != nil { return nil, err @@ -1349,9 +1402,9 @@ func (s *RPCServer) CancelBatchOrders(_ context.Context, r *gctrpc.CancelBatchOr // CancelAllOrders cancels all orders, filterable by exchange func (s *RPCServer) CancelAllOrders(_ context.Context, r *gctrpc.CancelAllOrdersRequest) (*gctrpc.CancelAllOrdersResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return &gctrpc.CancelAllOrdersResponse{}, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } resp, err := exch.CancelAllOrders(nil) @@ -1374,7 +1427,12 @@ func (s *RPCServer) ModifyOrder(_ context.Context, r *gctrpc.ModifyOrderRequest) Base: currency.NewCode(r.Pair.Base), Quote: currency.NewCode(r.Pair.Quote), } - exch := s.GetExchangeByName(r.Exchange) + + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, assetType, pair) if err != nil { return nil, err @@ -1421,7 +1479,11 @@ func (s *RPCServer) AddEvent(_ context.Context, r *gctrpc.AddEventRequest) (*gct return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, p) if err != nil { return nil, err @@ -1447,9 +1509,9 @@ func (s *RPCServer) RemoveEvent(_ context.Context, r *gctrpc.RemoveEventRequest) // GetCryptocurrencyDepositAddresses returns a list of cryptocurrency deposit // addresses specified by an exchange func (s *RPCServer) GetCryptocurrencyDepositAddresses(_ context.Context, r *gctrpc.GetCryptocurrencyDepositAddressesRequest) (*gctrpc.GetCryptocurrencyDepositAddressesResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + _, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } result, err := s.GetCryptocurrencyDepositAddressesByExchange(r.Exchange) @@ -1459,9 +1521,9 @@ func (s *RPCServer) GetCryptocurrencyDepositAddresses(_ context.Context, r *gctr // GetCryptocurrencyDepositAddress returns a cryptocurrency deposit address // specified by exchange and cryptocurrency func (s *RPCServer) GetCryptocurrencyDepositAddress(_ context.Context, r *gctrpc.GetCryptocurrencyDepositAddressRequest) (*gctrpc.GetCryptocurrencyDepositAddressResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + _, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } addr, err := s.GetExchangeCryptocurrencyDepositAddress(r.Exchange, "", currency.NewCode(r.Cryptocurrency)) @@ -1471,9 +1533,9 @@ func (s *RPCServer) GetCryptocurrencyDepositAddress(_ context.Context, r *gctrpc // WithdrawCryptocurrencyFunds withdraws cryptocurrency funds specified by // exchange func (s *RPCServer) WithdrawCryptocurrencyFunds(_ context.Context, r *gctrpc.WithdrawCryptoRequest) (*gctrpc.WithdrawResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + _, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } request := &withdraw.Request{ @@ -1502,12 +1564,11 @@ func (s *RPCServer) WithdrawCryptocurrencyFunds(_ context.Context, r *gctrpc.Wit // WithdrawFiatFunds withdraws fiat funds specified by exchange func (s *RPCServer) WithdrawFiatFunds(_ context.Context, r *gctrpc.WithdrawFiatRequest) (*gctrpc.WithdrawResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } - var bankAccount *banking.Account bankAccount, err := banking.GetBankAccountByID(r.BankAccountId) if err != nil { base := exch.GetBase() @@ -1606,9 +1667,9 @@ func (s *RPCServer) WithdrawalEventByID(_ context.Context, r *gctrpc.WithdrawalE func (s *RPCServer) WithdrawalEventsByExchange(_ context.Context, r *gctrpc.WithdrawalEventsByExchangeRequest) (*gctrpc.WithdrawalEventsByExchangeResponse, error) { if !s.Config.Database.Enabled { if r.Id == "" { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } c := currency.NewCode(strings.ToUpper(r.Currency)) @@ -1740,7 +1801,11 @@ func (s *RPCServer) SetExchangePair(_ context.Context, r *gctrpc.SetExchangePair return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, currency.Pair{}) if err != nil { return nil, err @@ -1821,7 +1886,11 @@ func (s *RPCServer) GetOrderbookStream(r *gctrpc.GetOrderbookStreamRequest, stre Quote: currency.NewCode(r.Pair.Quote), } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return err + } + err = checkParams(r.Exchange, exch, a, p) if err != nil { return err @@ -1867,8 +1936,8 @@ func (s *RPCServer) GetExchangeOrderbookStream(r *gctrpc.GetExchangeOrderbookStr return errExchangeNameUnset } - if exch := s.GetExchangeByName(r.Exchange); exch == nil { - return ErrExchangeNotFound + if _, err := s.GetExchangeByName(r.Exchange); err != nil { + return err } pipe, err := orderbook.SubscribeToExchangeOrderbooks(r.Exchange) @@ -1923,8 +1992,8 @@ func (s *RPCServer) GetTickerStream(r *gctrpc.GetTickerStreamRequest, stream gct return errExchangeNameUnset } - if exch := s.GetExchangeByName(r.Exchange); exch == nil { - return ErrExchangeNotFound + if _, err := s.GetExchangeByName(r.Exchange); err != nil { + return err } a, err := asset.New(r.AssetType) @@ -1990,8 +2059,8 @@ func (s *RPCServer) GetExchangeTickerStream(r *gctrpc.GetExchangeTickerStreamReq return errExchangeNameUnset } - if exch := s.GetExchangeByName(r.Exchange); exch == nil { - return ErrExchangeNotFound + if _, err := s.GetExchangeByName(r.Exchange); err != nil { + return err } pipe, err := ticker.SubscribeToExchangeTickers(r.Exchange) @@ -2110,7 +2179,11 @@ func (s *RPCServer) GetHistoricCandles(_ context.Context, r *gctrpc.GetHistoricC return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, pair) if err != nil { return nil, err @@ -2541,9 +2614,9 @@ func (s *RPCServer) GCTScriptAutoLoadToggle(_ context.Context, r *gctrpc.GCTScri // SetExchangeAsset enables or disables an exchanges asset type func (s *RPCServer) SetExchangeAsset(_ context.Context, r *gctrpc.SetExchangeAssetRequest) (*gctrpc.GenericResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } exchCfg, err := s.Config.GetExchangeConfig(r.Exchange) @@ -2579,9 +2652,9 @@ func (s *RPCServer) SetExchangeAsset(_ context.Context, r *gctrpc.SetExchangeAss // SetAllExchangePairs enables or disables an exchanges pairs func (s *RPCServer) SetAllExchangePairs(_ context.Context, r *gctrpc.SetExchangeAllPairsRequest) (*gctrpc.GenericResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } exchCfg, err := s.Config.GetExchangeConfig(r.Exchange) @@ -2627,9 +2700,9 @@ func (s *RPCServer) SetAllExchangePairs(_ context.Context, r *gctrpc.SetExchange // will update the available pairs list and remove any assets that are disabled // by the exchange func (s *RPCServer) UpdateExchangeSupportedPairs(_ context.Context, r *gctrpc.UpdateExchangeSupportedPairsRequest) (*gctrpc.GenericResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } base := exch.GetBase() @@ -2642,7 +2715,7 @@ func (s *RPCServer) UpdateExchangeSupportedPairs(_ context.Context, r *gctrpc.Up errors.New("cannot auto pair update for exchange, a manual update is needed") } - err := exch.UpdateTradablePairs(false) + err = exch.UpdateTradablePairs(false) if err != nil { return nil, err } @@ -2658,9 +2731,9 @@ func (s *RPCServer) UpdateExchangeSupportedPairs(_ context.Context, r *gctrpc.Up // GetExchangeAssets returns the supported asset types func (s *RPCServer) GetExchangeAssets(_ context.Context, r *gctrpc.GetExchangeAssetsRequest) (*gctrpc.GetExchangeAssetsResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } return &gctrpc.GetExchangeAssetsResponse{ @@ -2670,9 +2743,9 @@ func (s *RPCServer) GetExchangeAssets(_ context.Context, r *gctrpc.GetExchangeAs // WebsocketGetInfo returns websocket connection information func (s *RPCServer) WebsocketGetInfo(_ context.Context, r *gctrpc.WebsocketGetInfoRequest) (*gctrpc.WebsocketGetInfoResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } w, err := exch.GetWebsocket() @@ -2692,9 +2765,9 @@ func (s *RPCServer) WebsocketGetInfo(_ context.Context, r *gctrpc.WebsocketGetIn // WebsocketSetEnabled enables or disables the websocket client func (s *RPCServer) WebsocketSetEnabled(_ context.Context, r *gctrpc.WebsocketSetEnabledRequest) (*gctrpc.GenericResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } w, err := exch.GetWebsocket() @@ -2727,9 +2800,9 @@ func (s *RPCServer) WebsocketSetEnabled(_ context.Context, r *gctrpc.WebsocketSe // WebsocketGetSubscriptions returns websocket subscription analysis func (s *RPCServer) WebsocketGetSubscriptions(_ context.Context, r *gctrpc.WebsocketGetSubscriptionsRequest) (*gctrpc.WebsocketGetSubscriptionsResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } w, err := exch.GetWebsocket() @@ -2758,9 +2831,9 @@ func (s *RPCServer) WebsocketGetSubscriptions(_ context.Context, r *gctrpc.Webso // WebsocketSetProxy sets client websocket connection proxy func (s *RPCServer) WebsocketSetProxy(_ context.Context, r *gctrpc.WebsocketSetProxyRequest) (*gctrpc.GenericResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } w, err := exch.GetWebsocket() @@ -2780,9 +2853,9 @@ func (s *RPCServer) WebsocketSetProxy(_ context.Context, r *gctrpc.WebsocketSetP // WebsocketSetURL sets exchange websocket client connection URL func (s *RPCServer) WebsocketSetURL(_ context.Context, r *gctrpc.WebsocketSetURLRequest) (*gctrpc.GenericResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } w, err := exch.GetWebsocket() @@ -2817,7 +2890,11 @@ func (s *RPCServer) GetSavedTrades(_ context.Context, r *gctrpc.GetSavedTradesRe return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, p) if err != nil { return nil, err @@ -2889,7 +2966,11 @@ func (s *RPCServer) ConvertTradesToCandles(_ context.Context, r *gctrpc.ConvertT return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, p) if err != nil { return nil, err @@ -2957,7 +3038,11 @@ func (s *RPCServer) FindMissingSavedCandleIntervals(_ context.Context, r *gctrpc return nil, err } - exch := s.GetExchangeByName(r.ExchangeName) + exch, err := s.GetExchangeByName(r.ExchangeName) + if err != nil { + return nil, err + } + err = checkParams(r.ExchangeName, exch, a, p) if err != nil { return nil, err @@ -3045,7 +3130,11 @@ func (s *RPCServer) FindMissingSavedTradeIntervals(_ context.Context, r *gctrpc. return nil, err } - exch := s.GetExchangeByName(r.ExchangeName) + exch, err := s.GetExchangeByName(r.ExchangeName) + if err != nil { + return nil, err + } + err = checkParams(r.ExchangeName, exch, a, p) if err != nil { return nil, err @@ -3129,10 +3218,11 @@ func (s *RPCServer) FindMissingSavedTradeIntervals(_ context.Context, r *gctrpc. // SetExchangeTradeProcessing allows the setting of exchange trade processing func (s *RPCServer) SetExchangeTradeProcessing(_ context.Context, r *gctrpc.SetExchangeTradeProcessingRequest) (*gctrpc.GenericResponse, error) { - exch := s.GetExchangeByName(r.Exchange) - if exch == nil { - return nil, errExchangeNotLoaded + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err } + b := exch.GetBase() b.SetSaveTradeDataStatus(r.Status) @@ -3157,7 +3247,11 @@ func (s *RPCServer) GetHistoricTrades(r *gctrpc.GetSavedTradesRequest, stream gc return err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return err + } + err = checkParams(r.Exchange, exch, a, cp) if err != nil { return err @@ -3233,7 +3327,11 @@ func (s *RPCServer) GetRecentTrades(_ context.Context, r *gctrpc.GetSavedTradesR return nil, err } - exch := s.GetExchangeByName(r.Exchange) + exch, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, exch, a, cp) if err != nil { return nil, err @@ -3269,7 +3367,7 @@ func checkParams(exchName string, e exchange.IBotExchange, a asset.Item, p curre return fmt.Errorf("%s %w", exchName, errExchangeNotLoaded) } if !e.IsEnabled() { - return fmt.Errorf("%s %w", exchName, ErrExchangeNotFound) + return fmt.Errorf("%s %w", exchName, errExchangeNotEnabled) } if a.IsValid() { b := e.GetBase() @@ -3455,7 +3553,12 @@ func (s *RPCServer) UpsertDataHistoryJob(_ context.Context, r *gctrpc.UpsertData Base: currency.NewCode(r.Pair.Base), Quote: currency.NewCode(r.Pair.Quote), } - e := s.GetExchangeByName(r.Exchange) + + e, err := s.GetExchangeByName(r.Exchange) + if err != nil { + return nil, err + } + err = checkParams(r.Exchange, e, a, p) if err != nil { return nil, err diff --git a/engine/rpcserver_test.go b/engine/rpcserver_test.go index b553e4b9259..ed7175792e5 100644 --- a/engine/rpcserver_test.go +++ b/engine/rpcserver_test.go @@ -247,7 +247,7 @@ func TestGetSavedTrades(t *testing.T) { Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat), End: time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC).Format(common.SimpleTimeFormat), }) - if !errors.Is(err, errExchangeNotLoaded) { + if !errors.Is(err, ErrExchangeNotFound) { t.Error(err) } _, err = s.GetSavedTrades(context.Background(), &gctrpc.GetSavedTradesRequest{ @@ -321,7 +321,7 @@ func TestConvertTradesToCandles(t *testing.T) { End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat), TimeInterval: int64(kline.OneHour.Duration()), }) - if !errors.Is(err, errExchangeNotLoaded) { + if !errors.Is(err, ErrExchangeNotFound) { t.Error(err) } @@ -456,8 +456,22 @@ func TestGetHistoricCandles(t *testing.T) { End: defaultEnd.Format(common.SimpleTimeFormat), AssetType: asset.Spot.String(), }) - if !errors.Is(err, errExchangeNotLoaded) { - t.Errorf("received '%v', expected '%v'", err, errExchangeNotLoaded) + if !errors.Is(err, errExchangeNameIsEmpty) { + t.Errorf("received '%v', expected '%v'", err, errExchangeNameIsEmpty) + } + + _, err = s.GetHistoricCandles(context.Background(), &gctrpc.GetHistoricCandlesRequest{ + Exchange: "bruh", + Pair: &gctrpc.CurrencyPair{ + Base: cp.Base.String(), + Quote: cp.Quote.String(), + }, + Start: defaultStart.Format(common.SimpleTimeFormat), + End: defaultEnd.Format(common.SimpleTimeFormat), + AssetType: asset.Spot.String(), + }) + if !errors.Is(err, ErrExchangeNotFound) { + t.Errorf("received '%v', expected '%v'", err, ErrExchangeNotFound) } _, err = s.GetHistoricCandles(context.Background(), &gctrpc.GetHistoricCandlesRequest{ @@ -844,7 +858,7 @@ func TestGetRecentTrades(t *testing.T) { Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat), End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat), }) - if !errors.Is(err, errExchangeNotLoaded) { + if !errors.Is(err, ErrExchangeNotFound) { t.Error(err) } _, err = s.GetRecentTrades(context.Background(), &gctrpc.GetSavedTradesRequest{ @@ -880,7 +894,7 @@ func TestGetHistoricTrades(t *testing.T) { Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat), End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat), }, nil) - if !errors.Is(err, errExchangeNotLoaded) { + if !errors.Is(err, ErrExchangeNotFound) { t.Error(err) } err = s.GetHistoricTrades(&gctrpc.GetSavedTradesRequest{ @@ -1009,8 +1023,17 @@ func TestGetOrders(t *testing.T) { AssetType: asset.Spot.String(), Pair: p, }) - if !errors.Is(err, errExchangeNotLoaded) { - t.Errorf("received '%v', expected '%v'", errExchangeNotLoaded, err) + if !errors.Is(err, errExchangeNameIsEmpty) { + t.Errorf("received '%v', expected '%v'", errExchangeNameIsEmpty, err) + } + + _, err = s.GetOrders(context.Background(), &gctrpc.GetOrdersRequest{ + Exchange: "bruh", + AssetType: asset.Spot.String(), + Pair: p, + }) + if !errors.Is(err, ErrExchangeNotFound) { + t.Errorf("received '%v', expected '%v'", ErrExchangeNotFound, err) } _, err = s.GetOrders(context.Background(), &gctrpc.GetOrdersRequest{ @@ -1112,8 +1135,8 @@ func TestGetOrder(t *testing.T) { Pair: p, Asset: "spot", }) - if !errors.Is(err, errExchangeNotLoaded) { - t.Errorf("received '%v', expected '%v'", err, errExchangeNotLoaded) + if !errors.Is(err, ErrExchangeNotFound) { + t.Errorf("received '%v', expected '%v'", err, ErrExchangeNotFound) } _, err = s.GetOrder(context.Background(), &gctrpc.GetOrderRequest{ @@ -1165,14 +1188,9 @@ func TestCheckVars(t *testing.T) { } e = &binance.Binance{} - _, ok := e.(*binance.Binance) - if !ok { - t.Fatal("invalid ibotexchange interface") - } - err = checkParams("Binance", e, asset.Spot, currency.NewPair(currency.BTC, currency.USDT)) - if !errors.Is(err, ErrExchangeNotFound) { - t.Errorf("expected %v, got %v", ErrExchangeNotFound, err) + if !errors.Is(err, errExchangeNotEnabled) { + t.Errorf("expected %v, got %v", errExchangeNotEnabled, err) } e.SetEnabled(true) @@ -1646,8 +1664,17 @@ func TestGetManagedOrders(t *testing.T) { AssetType: asset.Spot.String(), Pair: p, }) - if !errors.Is(err, errExchangeNotLoaded) { - t.Errorf("received '%v', expected '%v'", errExchangeNotLoaded, err) + if !errors.Is(err, errExchangeNameIsEmpty) { + t.Errorf("received '%v', expected '%v'", errExchangeNameIsEmpty, err) + } + + _, err = s.GetManagedOrders(context.Background(), &gctrpc.GetOrdersRequest{ + Exchange: "bruh", + AssetType: asset.Spot.String(), + Pair: p, + }) + if !errors.Is(err, ErrExchangeNotFound) { + t.Errorf("received '%v', expected '%v'", ErrExchangeNotFound, err) } _, err = s.GetManagedOrders(context.Background(), &gctrpc.GetOrdersRequest{ @@ -1733,10 +1760,14 @@ func TestRPCServer_GetTicker_LastUpdatedNanos(t *testing.T) { // Make a dummy pair we'll be using for this test. pair := currency.NewPairWithDelimiter("XXXXX", "YYYYY", "") - // Create a mock-up RPCServer and add our newly made pair to its list of available - // and enabled pairs. + // Create a mock-up RPCServer and add our newly made pair to its list of + // available and enabled pairs. server := RPCServer{Engine: RPCTestSetup(t)} - b := server.ExchangeManager.GetExchangeByName(testExchange).GetBase() + exch, err := server.GetExchangeByName(testExchange) + if err != nil { + t.Fatal(err) + } + b := exch.GetBase() b.CurrencyPairs.Pairs[asset.Spot].Available = append( b.CurrencyPairs.Pairs[asset.Spot].Available, pair, diff --git a/engine/subsystem_types.go b/engine/subsystem_types.go index 461fe2a4004..7d6c5337ea5 100644 --- a/engine/subsystem_types.go +++ b/engine/subsystem_types.go @@ -10,7 +10,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" - "github.com/thrasher-corp/gocryptotrader/exchanges/stream" "github.com/thrasher-corp/gocryptotrader/exchanges/ticker" "github.com/thrasher-corp/gocryptotrader/portfolio" ) @@ -43,7 +42,7 @@ var ( // so that subsystems can use some functionality type iExchangeManager interface { GetExchanges() []exchange.IBotExchange - GetExchangeByName(string) exchange.IBotExchange + GetExchangeByName(string) (exchange.IBotExchange, error) } // iCommsManager limits exposure of accessible functions to communication manager @@ -72,13 +71,6 @@ type iBot interface { SetupExchanges() error } -// iWebsocketDataReceiver limits exposure of accessible functions to websocket data receiver -type iWebsocketDataReceiver interface { - IsRunning() bool - WebsocketDataReceiver(ws *stream.Websocket) - WebsocketDataHandler(string, interface{}) error -} - // iCurrencyPairSyncer defines a limited scoped currency pair syncer type iCurrencyPairSyncer interface { IsRunning() bool diff --git a/engine/withdraw_manager.go b/engine/withdraw_manager.go index c418f743b14..27e834b9801 100644 --- a/engine/withdraw_manager.go +++ b/engine/withdraw_manager.go @@ -32,9 +32,9 @@ func (m *WithdrawManager) SubmitWithdrawal(req *withdraw.Request) (*withdraw.Res return nil, withdraw.ErrRequestCannotBeNil } - exch := m.exchangeManager.GetExchangeByName(req.Exchange) - if exch == nil { - return nil, ErrExchangeNotFound + exch, err := m.exchangeManager.GetExchangeByName(req.Exchange) + if err != nil { + return nil, err } resp := &withdraw.Response{ @@ -44,7 +44,6 @@ func (m *WithdrawManager) SubmitWithdrawal(req *withdraw.Request) (*withdraw.Res RequestDetails: *req, } - var err error if m.isDryRun { log.Warnln(log.Global, "Dry run enabled, no withdrawal request will be submitted or have an event created") resp.ID = withdraw.DryRunID @@ -108,9 +107,9 @@ func (m *WithdrawManager) WithdrawalEventByExchange(exchange string, limit int) if m == nil { return nil, ErrNilSubsystem } - exch := m.exchangeManager.GetExchangeByName(exchange) - if exch == nil { - return nil, ErrExchangeNotFound + _, err := m.exchangeManager.GetExchangeByName(exchange) + if err != nil { + return nil, err } return dbwithdraw.GetEventsByExchange(exchange, limit) @@ -121,9 +120,9 @@ func (m *WithdrawManager) WithdrawEventByDate(exchange string, start, end time.T if m == nil { return nil, ErrNilSubsystem } - exch := m.exchangeManager.GetExchangeByName(exchange) - if exch == nil { - return nil, ErrExchangeNotFound + _, err := m.exchangeManager.GetExchangeByName(exchange) + if err != nil { + return nil, err } return dbwithdraw.GetEventsByDate(exchange, start, end, limit) @@ -134,9 +133,9 @@ func (m *WithdrawManager) WithdrawalEventByExchangeID(exchange, id string) (*wit if m == nil { return nil, ErrNilSubsystem } - exch := m.exchangeManager.GetExchangeByName(exchange) - if exch == nil { - return nil, ErrExchangeNotFound + _, err := m.exchangeManager.GetExchangeByName(exchange) + if err != nil { + return nil, err } return dbwithdraw.GetEventByExchangeID(exchange, id) diff --git a/gctscript/wrappers/gct/exchange/exchange.go b/gctscript/wrappers/gct/exchange/exchange.go index 4a555de370e..3e580d77411 100644 --- a/gctscript/wrappers/gct/exchange/exchange.go +++ b/gctscript/wrappers/gct/exchange/exchange.go @@ -2,7 +2,6 @@ package exchange import ( "errors" - "fmt" "sort" "strconv" "time" @@ -30,12 +29,7 @@ func (e Exchange) Exchanges(enabledOnly bool) []string { // GetExchange returns IBotExchange for exchange or error if exchange is not found func (e Exchange) GetExchange(exch string) (exchange.IBotExchange, error) { - ex := engine.Bot.GetExchangeByName(exch) - if ex == nil { - return nil, fmt.Errorf("%v exchange not found", exch) - } - - return ex, nil + return engine.Bot.GetExchangeByName(exch) } // IsEnabled returns if requested exchange is enabled or disabled diff --git a/gctscript/wrappers/gct/exchange/exchange_test.go b/gctscript/wrappers/gct/exchange/exchange_test.go index fa2872f6b2f..5ed0e261b0f 100644 --- a/gctscript/wrappers/gct/exchange/exchange_test.go +++ b/gctscript/wrappers/gct/exchange/exchange_test.go @@ -220,8 +220,12 @@ func cleanup() { } func configureExchangeKeys() bool { - ex := engine.Bot.GetExchangeByName(exchName).GetBase() - ex.SetAPIKeys(exchAPIKEY, exchAPISECRET, exchClientID) - ex.SkipAuthCheck = true - return ex.ValidateAPICredentials() + ex, err := engine.Bot.GetExchangeByName(exchName) + if err != nil { + return false + } + b := ex.GetBase() + b.SetAPIKeys(exchAPIKEY, exchAPISECRET, exchClientID) + b.SkipAuthCheck = true + return b.ValidateAPICredentials() }