From 991dfed70594c3dd1b0ce7212044567d9dc64773 Mon Sep 17 00:00:00 2001 From: Rauno Ots Date: Wed, 23 Sep 2020 09:41:59 +0200 Subject: [PATCH] Engine: Refactor use of global Bot (#563) * refactor use of global Bot * make the dependency on having an existing running Engine more obvious * use explicit dependency of engine in RPCServer * reduce static dependencies in rpcserver * improve helpers * revert bad document update, add check for nil error in test * add basic start stop test * fix race condition in storage * skip the test because of race conditions * fix typo * add empty line --- cmd/config_builder/builder.go | 4 +- cmd/exchange_wrapper_coverage/main.go | 4 +- cmd/exchange_wrapper_issues/main.go | 10 +- currency/storage.go | 2 + engine/addr_helpers.go | 2 +- engine/connection.go | 9 +- engine/engine.go | 168 ++++++++-------- engine/engine_test.go | 17 ++ engine/exchange.go | 58 +++--- engine/exchange_test.go | 66 +++--- engine/fake_exchange_test.go | 2 +- engine/helpers.go | 190 +++++++++--------- engine/helpers_test.go | 103 +++++----- engine/orders.go | 10 +- engine/portfolio.go | 2 +- engine/restful_router.go | 24 +-- engine/restful_server.go | 8 +- engine/restful_server_test.go | 14 +- engine/routines.go | 2 +- engine/rpcserver.go | 152 +++++++------- engine/syncer.go | 4 +- engine/syncer_test.go | 2 +- engine/websocket.go | 10 +- engine/withdraw.go | 2 +- gctscript/wrappers/gct/exchange/exchange.go | 10 +- .../wrappers/gct/exchange/exchange_test.go | 2 +- 26 files changed, 450 insertions(+), 427 deletions(-) diff --git a/cmd/config_builder/builder.go b/cmd/config_builder/builder.go index 7f37453a483..6d6074ca93c 100644 --- a/cmd/config_builder/builder.go +++ b/cmd/config_builder/builder.go @@ -21,7 +21,7 @@ func main() { var wg sync.WaitGroup for x := range exchange.Exchanges { name := exchange.Exchanges[x] - err = engine.LoadExchange(name, true, &wg) + err = engine.Bot.LoadExchange(name, true, &wg) if err != nil { log.Printf("Failed to load exchange %s. Err: %s", name, err) continue @@ -31,7 +31,7 @@ func main() { log.Println("Done.") var cfgs []config.ExchangeConfig - exchanges := engine.GetExchanges() + exchanges := engine.Bot.GetExchanges() for x := range exchanges { var cfg *config.ExchangeConfig cfg, err = exchanges[x].GetDefaultConfig() diff --git a/cmd/exchange_wrapper_coverage/main.go b/cmd/exchange_wrapper_coverage/main.go index de6111f882e..3c3732e31f4 100644 --- a/cmd/exchange_wrapper_coverage/main.go +++ b/cmd/exchange_wrapper_coverage/main.go @@ -34,7 +34,7 @@ func main() { var wg sync.WaitGroup for x := range exchange.Exchanges { name := exchange.Exchanges[x] - err := engine.LoadExchange(name, true, &wg) + err := engine.Bot.LoadExchange(name, true, &wg) if err != nil { log.Printf("Failed to load exchange %s. Err: %s", name, err) continue @@ -46,7 +46,7 @@ func main() { log.Printf("Testing exchange wrappers..") results := make(map[string][]string) wg = sync.WaitGroup{} - exchanges := engine.GetExchanges() + exchanges := engine.Bot.GetExchanges() for x := range exchanges { wg.Add(1) go func(num int) { diff --git a/cmd/exchange_wrapper_issues/main.go b/cmd/exchange_wrapper_issues/main.go index 5cb63322910..c228ab728bc 100644 --- a/cmd/exchange_wrapper_issues/main.go +++ b/cmd/exchange_wrapper_issues/main.go @@ -32,14 +32,14 @@ import ( func main() { log.Println("Loading flags...") parseCLFlags() - var err error log.Println("Loading engine...") - engine.Bot, err = engine.New() + bot, err := engine.New() if err != nil { log.Fatalf("Failed to initialise engine. Err: %s", err) } + engine.Bot = bot - engine.Bot.Settings = engine.Settings{ + bot.Settings = engine.Settings{ DisableExchangeAutoPairUpdates: true, Verbose: verboseOverride, EnableExchangeHTTPRateLimiter: true, @@ -63,7 +63,7 @@ func main() { wrapperConfig.Exchanges[strings.ToLower(name)] = &config.APICredentialsConfig{} } if shouldLoadExchange(name) { - err = engine.LoadExchange(name, true, &wg) + err = bot.LoadExchange(name, true, &wg) if err != nil { log.Printf("Failed to load exchange %s. Err: %s", name, err) continue @@ -92,7 +92,7 @@ func main() { log.Println("Testing exchange wrappers..") var exchangeResponses []ExchangeResponses - exchs := engine.GetExchanges() + exchs := bot.GetExchanges() for x := range exchs { base := exchs[x].GetBase() if !base.Config.Enabled { diff --git a/currency/storage.go b/currency/storage.go index 4f5c7d60f7e..70457175fbd 100644 --- a/currency/storage.go +++ b/currency/storage.go @@ -743,6 +743,8 @@ func (s *Storage) IsVerbose() bool { // Shutdown shuts down the currency storage system and saves to currency.json func (s *Storage) Shutdown() error { + s.mtx.Lock() + defer s.mtx.Unlock() close(s.shutdown) s.wg.Wait() return s.WriteCurrencyDataToFile(s.path, true) diff --git a/engine/addr_helpers.go b/engine/addr_helpers.go index d3afee639e6..533f3b57362 100644 --- a/engine/addr_helpers.go +++ b/engine/addr_helpers.go @@ -95,6 +95,6 @@ func (d *DepositAddressManager) GetDepositAddressesByExchange(exchName string) ( // Sync synchronises all deposit addresses func (d *DepositAddressManager) Sync() { - result := GetExchangeCryptocurrencyDepositAddresses() + result := Bot.GetExchangeCryptocurrencyDepositAddresses() d.Store.Seed(result) } diff --git a/engine/connection.go b/engine/connection.go index 6a3a0abff1e..9eccd68f947 100644 --- a/engine/connection.go +++ b/engine/connection.go @@ -4,6 +4,7 @@ import ( "errors" "sync/atomic" + "github.com/thrasher-corp/gocryptotrader/config" "github.com/thrasher-corp/gocryptotrader/connchecker" "github.com/thrasher-corp/gocryptotrader/log" ) @@ -21,16 +22,16 @@ func (c *connectionManager) Started() bool { } // Start starts an instance of the connection manager -func (c *connectionManager) Start() error { +func (c *connectionManager) Start(conf *config.ConnectionMonitorConfig) error { if atomic.AddInt32(&c.started, 1) != 1 { return errors.New("connection manager already started") } log.Debugln(log.ConnectionMgr, "Connection manager starting...") var err error - c.conn, err = connchecker.New(Bot.Config.ConnectionMonitor.DNSList, - Bot.Config.ConnectionMonitor.PublicDomainList, - Bot.Config.ConnectionMonitor.CheckInterval) + c.conn, err = connchecker.New(conf.DNSList, + conf.PublicDomainList, + conf.CheckInterval) if err != nil { atomic.CompareAndSwapInt32(&c.started, 1, 0) return err diff --git a/engine/engine.go b/engine/engine.go index 5100d68c002..ec8bd18adcf 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -319,153 +319,153 @@ func PrintSettings(s *Settings) { } // Start starts the engine -func (e *Engine) Start() error { - if e == nil { +func (bot *Engine) Start() error { + if bot == nil { return errors.New("engine instance is nil") } - if e.Settings.EnableDatabaseManager { - if err := e.DatabaseManager.Start(); err != nil { + if bot.Settings.EnableDatabaseManager { + if err := bot.DatabaseManager.Start(); err != nil { gctlog.Errorf(gctlog.Global, "Database manager unable to start: %v", err) } } - if e.Settings.EnableDispatcher { - if err := dispatch.Start(e.Settings.DispatchMaxWorkerAmount, e.Settings.DispatchJobsLimit); err != nil { + if bot.Settings.EnableDispatcher { + if err := dispatch.Start(bot.Settings.DispatchMaxWorkerAmount, bot.Settings.DispatchJobsLimit); err != nil { gctlog.Errorf(gctlog.DispatchMgr, "Dispatcher unable to start: %v", err) } } // Sets up internet connectivity monitor - if e.Settings.EnableConnectivityMonitor { - if err := e.ConnectionManager.Start(); err != nil { + if bot.Settings.EnableConnectivityMonitor { + if err := bot.ConnectionManager.Start(&bot.Config.ConnectionMonitor); err != nil { gctlog.Errorf(gctlog.Global, "Connection manager unable to start: %v", err) } } - if e.Settings.EnableNTPClient { - if err := e.NTPManager.Start(); err != nil { + if bot.Settings.EnableNTPClient { + if err := bot.NTPManager.Start(); err != nil { gctlog.Errorf(gctlog.Global, "NTP manager unable to start: %v", err) } } - e.Uptime = time.Now() - gctlog.Debugf(gctlog.Global, "Bot '%s' started.\n", e.Config.Name) - gctlog.Debugf(gctlog.Global, "Using data dir: %s\n", e.Settings.DataDir) - if *e.Config.Logging.Enabled && strings.Contains(e.Config.Logging.Output, "file") { + bot.Uptime = time.Now() + gctlog.Debugf(gctlog.Global, "Bot '%s' started.\n", bot.Config.Name) + gctlog.Debugf(gctlog.Global, "Using data dir: %s\n", bot.Settings.DataDir) + if *bot.Config.Logging.Enabled && strings.Contains(bot.Config.Logging.Output, "file") { gctlog.Debugf(gctlog.Global, "Using log file: %s\n", - filepath.Join(gctlog.LogPath, e.Config.Logging.LoggerFileConfig.FileName)) + filepath.Join(gctlog.LogPath, bot.Config.Logging.LoggerFileConfig.FileName)) } gctlog.Debugf(gctlog.Global, "Using %d out of %d logical processors for runtime performance\n", runtime.GOMAXPROCS(-1), runtime.NumCPU()) - enabledExchanges := e.Config.CountEnabledExchanges() - if e.Settings.EnableAllExchanges { - enabledExchanges = len(e.Config.Exchanges) + enabledExchanges := bot.Config.CountEnabledExchanges() + if bot.Settings.EnableAllExchanges { + enabledExchanges = len(bot.Config.Exchanges) } gctlog.Debugln(gctlog.Global, "EXCHANGE COVERAGE") gctlog.Debugf(gctlog.Global, "\t Available Exchanges: %d. Enabled Exchanges: %d.\n", - len(e.Config.Exchanges), enabledExchanges) + len(bot.Config.Exchanges), enabledExchanges) - if e.Settings.ExchangePurgeCredentials { + if bot.Settings.ExchangePurgeCredentials { gctlog.Debugln(gctlog.Global, "Purging exchange API credentials.") - e.Config.PurgeExchangeAPICredentials() + bot.Config.PurgeExchangeAPICredentials() } gctlog.Debugln(gctlog.Global, "Setting up exchanges..") - SetupExchanges() - if Bot.exchangeManager.Len() == 0 { + bot.SetupExchanges() + if bot.exchangeManager.Len() == 0 { return errors.New("no exchanges are loaded") } - if e.Settings.EnableCommsRelayer { - if err := e.CommsManager.Start(); err != nil { + if bot.Settings.EnableCommsRelayer { + if err := bot.CommsManager.Start(); err != nil { gctlog.Errorf(gctlog.Global, "Communications manager unable to start: %v\n", err) } } err := currency.RunStorageUpdater(currency.BotOverrides{ - Coinmarketcap: e.Settings.EnableCoinmarketcapAnalysis, - FxCurrencyConverter: e.Settings.EnableCurrencyConverter, - FxCurrencyLayer: e.Settings.EnableCurrencyLayer, - FxFixer: e.Settings.EnableFixer, - FxOpenExchangeRates: e.Settings.EnableOpenExchangeRates, + Coinmarketcap: bot.Settings.EnableCoinmarketcapAnalysis, + FxCurrencyConverter: bot.Settings.EnableCurrencyConverter, + FxCurrencyLayer: bot.Settings.EnableCurrencyLayer, + FxFixer: bot.Settings.EnableFixer, + FxOpenExchangeRates: bot.Settings.EnableOpenExchangeRates, }, ¤cy.MainConfiguration{ - ForexProviders: e.Config.GetForexProviders(), - CryptocurrencyProvider: coinmarketcap.Settings(e.Config.Currency.CryptocurrencyProvider), - Cryptocurrencies: e.Config.Currency.Cryptocurrencies, - FiatDisplayCurrency: e.Config.Currency.FiatDisplayCurrency, - CurrencyDelay: e.Config.Currency.CurrencyFileUpdateDuration, - FxRateDelay: e.Config.Currency.ForeignExchangeUpdateDuration, + ForexProviders: bot.Config.GetForexProviders(), + CryptocurrencyProvider: coinmarketcap.Settings(bot.Config.Currency.CryptocurrencyProvider), + Cryptocurrencies: bot.Config.Currency.Cryptocurrencies, + FiatDisplayCurrency: bot.Config.Currency.FiatDisplayCurrency, + CurrencyDelay: bot.Config.Currency.CurrencyFileUpdateDuration, + FxRateDelay: bot.Config.Currency.ForeignExchangeUpdateDuration, }, - e.Settings.DataDir) + bot.Settings.DataDir) if err != nil { gctlog.Errorf(gctlog.Global, "Currency updater system failed to start %v", err) } - if e.Settings.EnableGRPC { - go StartRPCServer() + if bot.Settings.EnableGRPC { + go StartRPCServer(bot) } - if e.Settings.EnableDeprecatedRPC { - go StartRESTServer() + if bot.Settings.EnableDeprecatedRPC { + go StartRESTServer(bot) } - if e.Settings.EnableWebsocketRPC { - go StartWebsocketServer() + if bot.Settings.EnableWebsocketRPC { + go StartWebsocketServer(bot) StartWebsocketHandler() } - if e.Settings.EnablePortfolioManager { - if err = e.PortfolioManager.Start(); err != nil { + if bot.Settings.EnablePortfolioManager { + if err = bot.PortfolioManager.Start(); err != nil { gctlog.Errorf(gctlog.Global, "Fund manager unable to start: %v", err) } } - if e.Settings.EnableDepositAddressManager { - e.DepositAddressManager = new(DepositAddressManager) - go e.DepositAddressManager.Sync() + if bot.Settings.EnableDepositAddressManager { + bot.DepositAddressManager = new(DepositAddressManager) + go bot.DepositAddressManager.Sync() } - if e.Settings.EnableOrderManager { - if err = e.OrderManager.Start(); err != nil { + if bot.Settings.EnableOrderManager { + if err = bot.OrderManager.Start(); err != nil { gctlog.Errorf(gctlog.Global, "Order manager unable to start: %v", err) } } - if e.Settings.EnableExchangeSyncManager { + if bot.Settings.EnableExchangeSyncManager { exchangeSyncCfg := CurrencyPairSyncerConfig{ - SyncTicker: e.Settings.EnableTickerSyncing, - SyncOrderbook: e.Settings.EnableOrderbookSyncing, - SyncTrades: e.Settings.EnableTradeSyncing, - SyncContinuously: e.Settings.SyncContinuously, - NumWorkers: e.Settings.SyncWorkers, - Verbose: e.Settings.Verbose, - SyncTimeout: e.Settings.SyncTimeout, + SyncTicker: bot.Settings.EnableTickerSyncing, + SyncOrderbook: bot.Settings.EnableOrderbookSyncing, + SyncTrades: bot.Settings.EnableTradeSyncing, + SyncContinuously: bot.Settings.SyncContinuously, + NumWorkers: bot.Settings.SyncWorkers, + Verbose: bot.Settings.Verbose, + SyncTimeout: bot.Settings.SyncTimeout, } - e.ExchangeCurrencyPairManager, err = NewCurrencyPairSyncer(exchangeSyncCfg) + bot.ExchangeCurrencyPairManager, err = NewCurrencyPairSyncer(exchangeSyncCfg) if err != nil { gctlog.Warnf(gctlog.Global, "Unable to initialise exchange currency pair syncer. Err: %s", err) } else { - go e.ExchangeCurrencyPairManager.Start() + go bot.ExchangeCurrencyPairManager.Start() } } - if e.Settings.EnableEventManager { + if bot.Settings.EnableEventManager { go EventManger() } - if e.Settings.EnableWebsocketRoutine { + if bot.Settings.EnableWebsocketRoutine { go WebsocketRoutine() } - if e.Settings.EnableGCTScriptManager { - if e.Config.GCTScript.Enabled { - if err := e.GctScriptManager.Start(); err != nil { + if bot.Settings.EnableGCTScriptManager { + if bot.Config.GCTScript.Enabled { + if err := bot.GctScriptManager.Start(); err != nil { gctlog.Errorf(gctlog.Global, "GCTScript manager unable to start: %v", err) } } @@ -475,50 +475,50 @@ func (e *Engine) Start() error { } // Stop correctly shuts down engine saving configuration files -func (e *Engine) Stop() { +func (bot *Engine) Stop() { gctlog.Debugln(gctlog.Global, "Engine shutting down..") if len(portfolio.Portfolio.Addresses) != 0 { - e.Config.Portfolio = portfolio.Portfolio + bot.Config.Portfolio = portfolio.Portfolio } - if e.GctScriptManager.Started() { - if err := e.GctScriptManager.Stop(); err != nil { + if bot.GctScriptManager.Started() { + if err := bot.GctScriptManager.Stop(); err != nil { gctlog.Errorf(gctlog.Global, "GCTScript manager unable to stop. Error: %v", err) } } - if e.OrderManager.Started() { - if err := e.OrderManager.Stop(); err != nil { + if bot.OrderManager.Started() { + if err := bot.OrderManager.Stop(); err != nil { gctlog.Errorf(gctlog.Global, "Order manager unable to stop. Error: %v", err) } } - if e.NTPManager.Started() { - if err := e.NTPManager.Stop(); err != nil { + if bot.NTPManager.Started() { + if err := bot.NTPManager.Stop(); err != nil { gctlog.Errorf(gctlog.Global, "NTP manager unable to stop. Error: %v", err) } } - if e.CommsManager.Started() { - if err := e.CommsManager.Stop(); err != nil { + if bot.CommsManager.Started() { + if err := bot.CommsManager.Stop(); err != nil { gctlog.Errorf(gctlog.Global, "Communication manager unable to stop. Error: %v", err) } } - if e.PortfolioManager.Started() { - if err := e.PortfolioManager.Stop(); err != nil { + if bot.PortfolioManager.Started() { + if err := bot.PortfolioManager.Stop(); err != nil { gctlog.Errorf(gctlog.Global, "Fund manager unable to stop. Error: %v", err) } } - if e.ConnectionManager.Started() { - if err := e.ConnectionManager.Stop(); err != nil { + if bot.ConnectionManager.Started() { + if err := bot.ConnectionManager.Stop(); err != nil { gctlog.Errorf(gctlog.Global, "Connection manager unable to stop. Error: %v", err) } } - if e.DatabaseManager.Started() { - if err := e.DatabaseManager.Stop(); err != nil { + if bot.DatabaseManager.Started() { + if err := bot.DatabaseManager.Stop(); err != nil { gctlog.Errorf(gctlog.Global, "Database manager unable to stop. Error: %v", err) } } @@ -533,8 +533,8 @@ func (e *Engine) Stop() { gctlog.Errorf(gctlog.Global, "Currency storage system. Error: %v", err) } - if !e.Settings.EnableDryRun { - err := e.Config.SaveConfig(e.Settings.ConfigFile, false) + if !bot.Settings.EnableDryRun { + err := bot.Config.SaveConfig(bot.Settings.ConfigFile, false) if err != nil { gctlog.Errorln(gctlog.Global, "Unable to save config.") } else { @@ -543,7 +543,7 @@ func (e *Engine) Stop() { } // Wait for services to gracefully shutdown - e.ServicesWG.Wait() + bot.ServicesWG.Wait() err := gctlog.CloseLogger() if err != nil { log.Printf("Failed to close logger. Error: %v\n", err) diff --git a/engine/engine_test.go b/engine/engine_test.go index e53387c261e..8abaf44d04a 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -71,3 +71,20 @@ func TestLoadConfigWithSettings(t *testing.T) { }) } } + +func TestStartStopDoesNotCausePanic(t *testing.T) { + t.Skip("Due to race condition with global config.Cfg being used from multiple tests and RPC server and REST proxy never properly stopped when engine.Stop() is called") + botOne, err := NewFromSettings(&Settings{ + ConfigFile: config.TestFile, + EnableDryRun: true, + }) + if err != nil { + t.Error(err) + } + + if err = botOne.Start(); err != nil { + t.Error(err) + } + + botOne.Stop() +} diff --git a/engine/exchange.go b/engine/exchange.go index 5c677ef9aa9..c960e823efc 100644 --- a/engine/exchange.go +++ b/engine/exchange.go @@ -139,26 +139,26 @@ func (e *exchangeManager) unloadExchange(exchangeName string) error { } // GetExchangeByName returns an exchange given an exchange name -func GetExchangeByName(exchName string) exchange.IBotExchange { - return Bot.exchangeManager.getExchangeByName(exchName) +func (bot *Engine) GetExchangeByName(exchName string) exchange.IBotExchange { + return bot.exchangeManager.getExchangeByName(exchName) } // UnloadExchange unloads an exchange by name -func UnloadExchange(exchName string) error { - return Bot.exchangeManager.unloadExchange(exchName) +func (bot *Engine) UnloadExchange(exchName string) error { + return bot.exchangeManager.unloadExchange(exchName) } // GetExchanges retrieves the loaded exchanges -func GetExchanges() []exchange.IBotExchange { - return Bot.exchangeManager.getExchanges() +func (bot *Engine) GetExchanges() []exchange.IBotExchange { + return bot.exchangeManager.getExchanges() } // LoadExchange loads an exchange by name -func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { +func (bot *Engine) LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { nameLower := strings.ToLower(name) var exch exchange.IBotExchange - if Bot.exchangeManager.getExchangeByName(nameLower) != nil { + if bot.exchangeManager.getExchangeByName(nameLower) != nil { return ErrExchangeAlreadyLoaded } @@ -228,12 +228,12 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { } exch.SetDefaults() - exchCfg, err := Bot.Config.GetExchangeConfig(name) + exchCfg, err := bot.Config.GetExchangeConfig(name) if err != nil { return err } - if Bot.Settings.EnableAllPairs { + if bot.Settings.EnableAllPairs { if exchCfg.CurrencyPairs != nil { dryrunParamInteraction("enableallpairs") assets := exchCfg.CurrencyPairs.GetAssetTypes() @@ -248,12 +248,12 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { } } - if Bot.Settings.EnableExchangeVerbose { + if bot.Settings.EnableExchangeVerbose { dryrunParamInteraction("exchangeverbose") exchCfg.Verbose = true } - if Bot.Settings.EnableExchangeWebsocketSupport { + if bot.Settings.EnableExchangeWebsocketSupport { dryrunParamInteraction("exchangewebsocketsupport") if exchCfg.Features != nil { if exchCfg.Features.Supports.Websocket { @@ -262,7 +262,7 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { } } - if Bot.Settings.EnableExchangeAutoPairUpdates { + if bot.Settings.EnableExchangeAutoPairUpdates { dryrunParamInteraction("exchangeautopairupdates") if exchCfg.Features != nil { if exchCfg.Features.Supports.RESTCapabilities.AutoPairUpdates { @@ -271,7 +271,7 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { } } - if Bot.Settings.DisableExchangeAutoPairUpdates { + if bot.Settings.DisableExchangeAutoPairUpdates { dryrunParamInteraction("exchangedisableautopairupdates") if exchCfg.Features != nil { if exchCfg.Features.Supports.RESTCapabilities.AutoPairUpdates { @@ -280,31 +280,31 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { } } - if Bot.Settings.HTTPUserAgent != "" { + if bot.Settings.HTTPUserAgent != "" { dryrunParamInteraction("httpuseragent") - exchCfg.HTTPUserAgent = Bot.Settings.HTTPUserAgent + exchCfg.HTTPUserAgent = bot.Settings.HTTPUserAgent } - if Bot.Settings.HTTPProxy != "" { + if bot.Settings.HTTPProxy != "" { dryrunParamInteraction("httpproxy") - exchCfg.ProxyAddress = Bot.Settings.HTTPProxy + exchCfg.ProxyAddress = bot.Settings.HTTPProxy } - if Bot.Settings.HTTPTimeout != exchange.DefaultHTTPTimeout { + if bot.Settings.HTTPTimeout != exchange.DefaultHTTPTimeout { dryrunParamInteraction("httptimeout") - exchCfg.HTTPTimeout = Bot.Settings.HTTPTimeout + exchCfg.HTTPTimeout = bot.Settings.HTTPTimeout } - if Bot.Settings.EnableExchangeHTTPDebugging { + if bot.Settings.EnableExchangeHTTPDebugging { dryrunParamInteraction("exchangehttpdebugging") - exchCfg.HTTPDebugging = Bot.Settings.EnableExchangeHTTPDebugging + exchCfg.HTTPDebugging = bot.Settings.EnableExchangeHTTPDebugging } - if Bot.Settings.EnableAllExchanges { + if bot.Settings.EnableAllExchanges { dryrunParamInteraction("enableallexchanges") } - if !Bot.Settings.EnableExchangeHTTPRateLimiter { + if !bot.Settings.EnableExchangeHTTPRateLimiter { log.Warnf(log.ExchangeSys, "Loaded exchange %s rate limiting has been turned off.\n", exch.GetName(), @@ -326,7 +326,7 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { return err } - Bot.exchangeManager.add(exch) + bot.exchangeManager.add(exch) base := exch.GetBase() if base.API.AuthenticatedSupport || @@ -356,15 +356,15 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { } // SetupExchanges sets up the exchanges used by the Bot -func SetupExchanges() { +func (bot *Engine) SetupExchanges() { var wg sync.WaitGroup - configs := Bot.Config.GetAllExchangeConfigs() + configs := bot.Config.GetAllExchangeConfigs() for x := range configs { - if !configs[x].Enabled && !Bot.Settings.EnableAllExchanges { + if !configs[x].Enabled && !bot.Settings.EnableAllExchanges { log.Debugf(log.ExchangeSys, "%s: Exchange support: Disabled\n", configs[x].Name) continue } - err := LoadExchange(configs[x].Name, true, &wg) + err := bot.LoadExchange(configs[x].Name, true, &wg) if err != nil { log.Errorf(log.ExchangeSys, "LoadExchange %s failed: %s\n", configs[x].Name, err) continue diff --git a/engine/exchange_test.go b/engine/exchange_test.go index ef5868303c2..5b96799dbb9 100644 --- a/engine/exchange_test.go +++ b/engine/exchange_test.go @@ -7,15 +7,15 @@ import ( ) func CleanupTest(t *testing.T) { - if GetExchangeByName(testExchange) != nil { - err := UnloadExchange(testExchange) + if Bot.GetExchangeByName(testExchange) != nil { + err := Bot.UnloadExchange(testExchange) if err != nil { t.Fatalf("CleanupTest: Failed to unload exchange: %s", err) } } - if GetExchangeByName(fakePassExchange) != nil { - err := UnloadExchange(fakePassExchange) + if Bot.GetExchangeByName(fakePassExchange) != nil { + err := Bot.UnloadExchange(fakePassExchange) if err != nil { t.Fatalf("CleanupTest: Failed to unload exchange: %s", err) @@ -69,13 +69,13 @@ func TestExchangeManagerRemoveExchange(t *testing.T) { } func TestCheckExchangeExists(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) - if GetExchangeByName(testExchange) == nil { + if e.GetExchangeByName(testExchange) == nil { t.Errorf("TestGetExchangeExists: Unable to find exchange") } - if GetExchangeByName("Asdsad") != nil { + if e.GetExchangeByName("Asdsad") != nil { t.Errorf("TestGetExchangeExists: Non-existent exchange found") } @@ -83,9 +83,9 @@ func TestCheckExchangeExists(t *testing.T) { } func TestGetExchangeByName(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) - exch := GetExchangeByName(testExchange) + exch := e.GetExchangeByName(testExchange) if exch == nil { t.Errorf("TestGetExchangeByName: Failed to get exchange") } @@ -95,7 +95,7 @@ func TestGetExchangeByName(t *testing.T) { } exch.SetEnabled(false) - bfx := GetExchangeByName(testExchange) + bfx := e.GetExchangeByName(testExchange) if bfx.IsEnabled() { t.Errorf("TestGetExchangeByName: Unexpected result") } @@ -104,7 +104,7 @@ func TestGetExchangeByName(t *testing.T) { t.Errorf("TestGetExchangeByName: Unexpected result") } - exch = GetExchangeByName("Asdasd") + exch = e.GetExchangeByName("Asdasd") if exch != nil { t.Errorf("TestGetExchangeByName: Non-existent exchange found") } @@ -113,27 +113,27 @@ func TestGetExchangeByName(t *testing.T) { } func TestUnloadExchange(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) - err := UnloadExchange("asdf") - if err.Error() != "exchange asdf not found" { + err := e.UnloadExchange("asdf") + if err == nil || err.Error() != "exchange asdf not found" { t.Errorf("TestUnloadExchange: Incorrect result: %s", err) } - err = UnloadExchange(testExchange) + err = e.UnloadExchange(testExchange) if err != nil { t.Errorf("TestUnloadExchange: Failed to get exchange. %s", err) } - err = UnloadExchange(fakePassExchange) + err = e.UnloadExchange(fakePassExchange) if err != nil { t.Errorf("TestUnloadExchange: Failed to unload exchange. %s", err) } - err = UnloadExchange(testExchange) + err = e.UnloadExchange(testExchange) if err != ErrNoExchangesLoaded { t.Errorf("TestUnloadExchange: Incorrect result: %s", err) @@ -143,63 +143,63 @@ func TestUnloadExchange(t *testing.T) { } func TestDryRunParamInteraction(t *testing.T) { - SetupTestHelpers(t) + bot := SetupTestHelpers(t) // Load bot as per normal, dry run and verbose for Bitfinex should be // disabled - exchCfg, err := Bot.Config.GetExchangeConfig(testExchange) + exchCfg, err := bot.Config.GetExchangeConfig(testExchange) if err != nil { t.Error(err) } - if Bot.Settings.EnableDryRun || + if bot.Settings.EnableDryRun || exchCfg.Verbose { t.Error("dryrun and verbose should have been disabled") } // Simulate overiding default settings and ensure that enabling exchange // verbose mode will be set on Bitfinex - if err = UnloadExchange(testExchange); err != nil { + if err = bot.UnloadExchange(testExchange); err != nil { t.Error(err) } - Bot.Settings.CheckParamInteraction = true - Bot.Settings.EnableExchangeVerbose = true - if err = LoadExchange(testExchange, false, nil); err != nil { + bot.Settings.CheckParamInteraction = true + bot.Settings.EnableExchangeVerbose = true + if err = bot.LoadExchange(testExchange, false, nil); err != nil { t.Error(err) } - exchCfg, err = Bot.Config.GetExchangeConfig(testExchange) + exchCfg, err = bot.Config.GetExchangeConfig(testExchange) if err != nil { t.Error(err) } - if !Bot.Settings.EnableDryRun || + if !bot.Settings.EnableDryRun || !exchCfg.Verbose { t.Error("dryrun and verbose should have been enabled") } - if err = UnloadExchange(testExchange); err != nil { + if err = bot.UnloadExchange(testExchange); err != nil { t.Error(err) } // Now set dryrun mode to false (via flagset and the previously enabled // setting), enable exchange verbose mode and verify that verbose mode // will be set on Bitfinex - Bot.Settings.EnableDryRun = false - Bot.Settings.CheckParamInteraction = true - Bot.Settings.EnableExchangeVerbose = true + bot.Settings.EnableDryRun = false + bot.Settings.CheckParamInteraction = true + bot.Settings.EnableExchangeVerbose = true flagSet["dryrun"] = true - if err = LoadExchange(testExchange, false, nil); err != nil { + if err = bot.LoadExchange(testExchange, false, nil); err != nil { t.Error(err) } - exchCfg, err = Bot.Config.GetExchangeConfig(testExchange) + exchCfg, err = bot.Config.GetExchangeConfig(testExchange) if err != nil { t.Error(err) } - if Bot.Settings.EnableDryRun || + if bot.Settings.EnableDryRun || !exchCfg.Verbose { t.Error("dryrun should be false and verbose should be true") } diff --git a/engine/fake_exchange_test.go b/engine/fake_exchange_test.go index 26905cebf16..5939f7ccd9c 100644 --- a/engine/fake_exchange_test.go +++ b/engine/fake_exchange_test.go @@ -30,7 +30,7 @@ type FakePassingExchange struct { // addPassingFakeExchange adds an exchange to engine tests where all funcs return a positive result func addPassingFakeExchange(baseExchangeName string) error { - testExch := GetExchangeByName(baseExchangeName) + testExch := Bot.GetExchangeByName(baseExchangeName) if testExch == nil { return ErrExchangeNotFound } diff --git a/engine/helpers.go b/engine/helpers.go index 93d873fa656..3fd5c11d327 100644 --- a/engine/helpers.go +++ b/engine/helpers.go @@ -40,20 +40,20 @@ var ( ) // GetSubsystemsStatus returns the status of various subsystems -func GetSubsystemsStatus() map[string]bool { +func (bot *Engine) GetSubsystemsStatus() map[string]bool { systems := make(map[string]bool) - systems["communications"] = Bot.CommsManager.Started() - systems["internet_monitor"] = Bot.ConnectionManager.Started() - systems["orders"] = Bot.OrderManager.Started() - systems["portfolio"] = Bot.PortfolioManager.Started() - systems["ntp_timekeeper"] = Bot.NTPManager.Started() - systems["database"] = Bot.DatabaseManager.Started() - systems["exchange_syncer"] = Bot.Settings.EnableExchangeSyncManager - systems["grpc"] = Bot.Settings.EnableGRPC - systems["grpc_proxy"] = Bot.Settings.EnableGRPCProxy - systems["gctscript"] = Bot.GctScriptManager.Started() - systems["deprecated_rpc"] = Bot.Settings.EnableDeprecatedRPC - systems["websocket_rpc"] = Bot.Settings.EnableWebsocketRPC + systems["communications"] = bot.CommsManager.Started() + systems["internet_monitor"] = bot.ConnectionManager.Started() + systems["orders"] = bot.OrderManager.Started() + systems["portfolio"] = bot.PortfolioManager.Started() + systems["ntp_timekeeper"] = bot.NTPManager.Started() + systems["database"] = bot.DatabaseManager.Started() + systems["exchange_syncer"] = bot.Settings.EnableExchangeSyncManager + systems["grpc"] = bot.Settings.EnableGRPC + systems["grpc_proxy"] = bot.Settings.EnableGRPCProxy + systems["gctscript"] = bot.GctScriptManager.Started() + systems["deprecated_rpc"] = bot.Settings.EnableDeprecatedRPC + systems["websocket_rpc"] = bot.Settings.EnableWebsocketRPC systems["dispatch"] = dispatch.IsRunning() return systems } @@ -87,55 +87,55 @@ func GetRPCEndpoints() map[string]RPCEndpoint { } // SetSubsystem enables or disables an engine subsystem -func SetSubsystem(subsys string, enable bool) error { +func (bot *Engine) SetSubsystem(subsys string, enable bool) error { switch strings.ToLower(subsys) { case "communications": if enable { - return Bot.CommsManager.Start() + return bot.CommsManager.Start() } - return Bot.CommsManager.Stop() + return bot.CommsManager.Stop() case "internet_monitor": if enable { - return Bot.ConnectionManager.Start() + return bot.ConnectionManager.Start(&bot.Config.ConnectionMonitor) } - return Bot.CommsManager.Stop() + return bot.CommsManager.Stop() case "orders": if enable { - return Bot.OrderManager.Start() + return bot.OrderManager.Start() } - return Bot.OrderManager.Stop() + return bot.OrderManager.Stop() case "portfolio": if enable { - return Bot.PortfolioManager.Start() + return bot.PortfolioManager.Start() } - return Bot.OrderManager.Stop() + return bot.OrderManager.Stop() case "ntp_timekeeper": if enable { - return Bot.NTPManager.Start() + return bot.NTPManager.Start() } - return Bot.NTPManager.Stop() + return bot.NTPManager.Stop() case "database": if enable { - return Bot.DatabaseManager.Start() + return bot.DatabaseManager.Start() } - return Bot.DatabaseManager.Stop() + return bot.DatabaseManager.Stop() case "exchange_syncer": if enable { - Bot.ExchangeCurrencyPairManager.Start() + bot.ExchangeCurrencyPairManager.Start() } - Bot.ExchangeCurrencyPairManager.Stop() + bot.ExchangeCurrencyPairManager.Stop() case "dispatch": if enable { - return dispatch.Start(Bot.Settings.DispatchMaxWorkerAmount, Bot.Settings.DispatchJobsLimit) + return dispatch.Start(bot.Settings.DispatchMaxWorkerAmount, bot.Settings.DispatchJobsLimit) } return dispatch.Stop() case "gctscript": if enable { vm.GCTScriptConfig.Enabled = true - return Bot.GctScriptManager.Start() + return bot.GctScriptManager.Start() } vm.GCTScriptConfig.Enabled = false - return Bot.GctScriptManager.Stop() + return bot.GctScriptManager.Stop() } return errors.New("subsystem not found") @@ -143,11 +143,11 @@ func SetSubsystem(subsys string, enable bool) error { // GetExchangeOTPs returns OTP codes for all exchanges which have a otpsecret // stored -func GetExchangeOTPs() (map[string]string, error) { +func (bot *Engine) GetExchangeOTPs() (map[string]string, error) { otpCodes := make(map[string]string) - for x := range Bot.Config.Exchanges { - if otpSecret := Bot.Config.Exchanges[x].API.Credentials.OTPSecret; otpSecret != "" { - exchName := Bot.Config.Exchanges[x].Name + for x := range bot.Config.Exchanges { + if otpSecret := bot.Config.Exchanges[x].API.Credentials.OTPSecret; otpSecret != "" { + exchName := bot.Config.Exchanges[x].Name o, err := totp.GenerateCode(otpSecret, time.Now()) if err != nil { log.Errorf(log.Global, "Unable to generate OTP code for exchange %s. Err: %s\n", @@ -167,13 +167,13 @@ func GetExchangeOTPs() (map[string]string, error) { // GetExchangeoOTPByName returns a OTP code for the desired exchange // if it exists -func GetExchangeoOTPByName(exchName string) (string, error) { - for x := range Bot.Config.Exchanges { - if !strings.EqualFold(Bot.Config.Exchanges[x].Name, exchName) { +func (bot *Engine) GetExchangeoOTPByName(exchName string) (string, error) { + for x := range bot.Config.Exchanges { + if !strings.EqualFold(bot.Config.Exchanges[x].Name, exchName) { continue } - if otpSecret := Bot.Config.Exchanges[x].API.Credentials.OTPSecret; otpSecret != "" { + if otpSecret := bot.Config.Exchanges[x].API.Credentials.OTPSecret; otpSecret != "" { return totp.GenerateCode(otpSecret, time.Now()) } } @@ -181,9 +181,9 @@ func GetExchangeoOTPByName(exchName string) (string, error) { } // GetAuthAPISupportedExchanges returns a list of auth api enabled exchanges -func GetAuthAPISupportedExchanges() []string { +func (bot *Engine) GetAuthAPISupportedExchanges() []string { var exchangeNames []string - exchanges := GetExchanges() + exchanges := bot.GetExchanges() for x := range exchanges { if !exchanges[x].GetAuthenticatedAPISupport(exchange.RestAuthentication) && !exchanges[x].GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { @@ -195,16 +195,16 @@ func GetAuthAPISupportedExchanges() []string { } // IsOnline returns whether or not the engine has Internet connectivity -func IsOnline() bool { - return Bot.ConnectionManager.IsOnline() +func (bot *Engine) IsOnline() bool { + return bot.ConnectionManager.IsOnline() } // GetAvailableExchanges returns a list of enabled exchanges -func GetAvailableExchanges() []string { +func (bot *Engine) GetAvailableExchanges() []string { var enExchanges []string - for x := range Bot.Config.Exchanges { - if Bot.Config.Exchanges[x].Enabled { - enExchanges = append(enExchanges, Bot.Config.Exchanges[x].Name) + for x := range bot.Config.Exchanges { + if bot.Config.Exchanges[x].Enabled { + enExchanges = append(enExchanges, bot.Config.Exchanges[x].Name) } } return enExchanges @@ -212,15 +212,15 @@ func GetAvailableExchanges() []string { // GetAllAvailablePairs returns a list of all available pairs on either enabled // or disabled exchanges -func GetAllAvailablePairs(enabledExchangesOnly bool, assetType asset.Item) currency.Pairs { +func (bot *Engine) GetAllAvailablePairs(enabledExchangesOnly bool, assetType asset.Item) currency.Pairs { var pairList currency.Pairs - for x := range Bot.Config.Exchanges { - if enabledExchangesOnly && !Bot.Config.Exchanges[x].Enabled { + for x := range bot.Config.Exchanges { + if enabledExchangesOnly && !bot.Config.Exchanges[x].Enabled { continue } - exchName := Bot.Config.Exchanges[x].Name - pairs, err := Bot.Config.GetAvailablePairs(exchName, assetType) + exchName := bot.Config.Exchanges[x].Name + pairs, err := bot.Config.GetAvailablePairs(exchName, assetType) if err != nil { continue } @@ -237,9 +237,9 @@ func GetAllAvailablePairs(enabledExchangesOnly bool, assetType asset.Item) curre // GetSpecificAvailablePairs returns a list of supported pairs based on specific // parameters -func GetSpecificAvailablePairs(enabledExchangesOnly, fiatPairs, includeUSDT, cryptoPairs bool, assetType asset.Item) currency.Pairs { +func (bot *Engine) GetSpecificAvailablePairs(enabledExchangesOnly, fiatPairs, includeUSDT, cryptoPairs bool, assetType asset.Item) currency.Pairs { var pairList currency.Pairs - supportedPairs := GetAllAvailablePairs(enabledExchangesOnly, assetType) + supportedPairs := bot.GetAllAvailablePairs(enabledExchangesOnly, assetType) for x := range supportedPairs { if fiatPairs { @@ -284,15 +284,15 @@ func IsRelatablePairs(p1, p2 currency.Pair, includeUSDT bool) bool { // MapCurrenciesByExchange returns a list of currency pairs mapped to an // exchange -func MapCurrenciesByExchange(p currency.Pairs, enabledExchangesOnly bool, assetType asset.Item) map[string]currency.Pairs { +func (bot *Engine) MapCurrenciesByExchange(p currency.Pairs, enabledExchangesOnly bool, assetType asset.Item) map[string]currency.Pairs { currencyExchange := make(map[string]currency.Pairs) for x := range p { - for y := range Bot.Config.Exchanges { - if enabledExchangesOnly && !Bot.Config.Exchanges[y].Enabled { + for y := range bot.Config.Exchanges { + if enabledExchangesOnly && !bot.Config.Exchanges[y].Enabled { continue } - exchName := Bot.Config.Exchanges[y].Name - if !Bot.Config.SupportsPair(exchName, p[x], assetType) { + exchName := bot.Config.Exchanges[y].Name + if !bot.Config.SupportsPair(exchName, p[x], assetType) { continue } @@ -315,15 +315,15 @@ func MapCurrenciesByExchange(p currency.Pairs, enabledExchangesOnly bool, assetT // GetExchangeNamesByCurrency returns a list of exchanges supporting // a currency pair based on whether the exchange is enabled or not -func GetExchangeNamesByCurrency(p currency.Pair, enabled bool, assetType asset.Item) []string { +func (bot *Engine) GetExchangeNamesByCurrency(p currency.Pair, enabled bool, assetType asset.Item) []string { var exchanges []string - for x := range Bot.Config.Exchanges { - if enabled != Bot.Config.Exchanges[x].Enabled { + for x := range bot.Config.Exchanges { + if enabled != bot.Config.Exchanges[x].Enabled { continue } - exchName := Bot.Config.Exchanges[x].Name - if !Bot.Config.SupportsPair(exchName, p, assetType) { + exchName := bot.Config.Exchanges[x].Name + if !bot.Config.SupportsPair(exchName, p, assetType) { continue } exchanges = append(exchanges, exchName) @@ -427,8 +427,8 @@ func GetRelatableCurrencies(p currency.Pair, incOrig, incUSDT bool) currency.Pai // GetSpecificOrderbook returns a specific orderbook given the currency, // exchangeName and assetType -func GetSpecificOrderbook(p currency.Pair, exchangeName string, assetType asset.Item) (*orderbook.Base, error) { - exch := GetExchangeByName(exchangeName) +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 } @@ -437,8 +437,8 @@ func GetSpecificOrderbook(p currency.Pair, exchangeName string, assetType asset. // GetSpecificTicker returns a specific ticker given the currency, // exchangeName and assetType -func GetSpecificTicker(p currency.Pair, exchangeName string, assetType asset.Item) (*ticker.Price, error) { - exch := GetExchangeByName(exchangeName) +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 } @@ -582,25 +582,25 @@ func SeedExchangeAccountInfo(accounts []account.Holdings) { } // GetCryptocurrenciesByExchange returns a list of cryptocurrencies the exchange supports -func GetCryptocurrenciesByExchange(exchangeName string, enabledExchangesOnly, enabledPairs bool, assetType asset.Item) ([]string, error) { +func (bot *Engine) GetCryptocurrenciesByExchange(exchangeName string, enabledExchangesOnly, enabledPairs bool, assetType asset.Item) ([]string, error) { var cryptocurrencies []string - for x := range Bot.Config.Exchanges { - if !strings.EqualFold(Bot.Config.Exchanges[x].Name, exchangeName) { + for x := range bot.Config.Exchanges { + if !strings.EqualFold(bot.Config.Exchanges[x].Name, exchangeName) { continue } - if enabledExchangesOnly && !Bot.Config.Exchanges[x].Enabled { + if enabledExchangesOnly && !bot.Config.Exchanges[x].Enabled { continue } var err error var pairs []currency.Pair if enabledPairs { - pairs, err = Bot.Config.GetEnabledPairs(exchangeName, assetType) + pairs, err = bot.Config.GetEnabledPairs(exchangeName, assetType) if err != nil { return nil, err } } else { - pairs, err = Bot.Config.GetAvailablePairs(exchangeName, assetType) + pairs, err = bot.Config.GetAvailablePairs(exchangeName, assetType) if err != nil { return nil, err } @@ -622,12 +622,12 @@ func GetCryptocurrenciesByExchange(exchangeName string, enabledExchangesOnly, en } // GetCryptocurrencyDepositAddressesByExchange returns the cryptocurrency deposit addresses for a particular exchange -func GetCryptocurrencyDepositAddressesByExchange(exchName string) (map[string]string, error) { - if Bot.DepositAddressManager != nil { - return Bot.DepositAddressManager.GetDepositAddressesByExchange(exchName) +func (bot *Engine) GetCryptocurrencyDepositAddressesByExchange(exchName string) (map[string]string, error) { + if bot.DepositAddressManager != nil { + return bot.DepositAddressManager.GetDepositAddressesByExchange(exchName) } - result := GetExchangeCryptocurrencyDepositAddresses() + result := bot.GetExchangeCryptocurrencyDepositAddresses() r, ok := result[exchName] if !ok { return nil, ErrExchangeNotFound @@ -637,12 +637,12 @@ func GetCryptocurrencyDepositAddressesByExchange(exchName string) (map[string]st // GetExchangeCryptocurrencyDepositAddress returns the cryptocurrency deposit address for a particular // exchange -func GetExchangeCryptocurrencyDepositAddress(exchName, accountID string, item currency.Code) (string, error) { - if Bot.DepositAddressManager != nil { - return Bot.DepositAddressManager.GetDepositAddressByExchange(exchName, item) +func (bot *Engine) GetExchangeCryptocurrencyDepositAddress(exchName, accountID string, item currency.Code) (string, error) { + if bot.DepositAddressManager != nil { + return bot.DepositAddressManager.GetDepositAddressByExchange(exchName, item) } - exch := GetExchangeByName(exchName) + exch := bot.GetExchangeByName(exchName) if exch == nil { return "", ErrExchangeNotFound } @@ -650,19 +650,19 @@ func GetExchangeCryptocurrencyDepositAddress(exchName, accountID string, item cu } // GetExchangeCryptocurrencyDepositAddresses obtains an exchanges deposit cryptocurrency list -func GetExchangeCryptocurrencyDepositAddresses() map[string]map[string]string { +func (bot *Engine) GetExchangeCryptocurrencyDepositAddresses() map[string]map[string]string { result := make(map[string]map[string]string) - exchanges := GetExchanges() + exchanges := bot.GetExchanges() for x := range exchanges { exchName := exchanges[x].GetName() if !exchanges[x].GetAuthenticatedAPISupport(exchange.RestAuthentication) { - if Bot.Settings.Verbose { + if bot.Settings.Verbose { log.Debugf(log.ExchangeSys, "GetExchangeCryptocurrencyDepositAddresses: Skippping %s due to disabled authenticated API support.\n", exchName) } continue } - cryptoCurrencies, err := GetCryptocurrenciesByExchange(exchName, true, true, asset.Spot) + cryptoCurrencies, err := bot.GetCryptocurrenciesByExchange(exchName, true, true, asset.Spot) if err != nil { log.Debugf(log.ExchangeSys, "%s failed to get cryptocurrency deposit addresses. Err: %s\n", exchName, err) continue @@ -691,19 +691,19 @@ func FormatCurrency(p currency.Pair) currency.Pair { } // GetExchangeNames returns a list of enabled or disabled exchanges -func GetExchangeNames(enabledOnly bool) []string { - exchangeNames := GetAvailableExchanges() +func (bot *Engine) GetExchangeNames(enabledOnly bool) []string { + exchangeNames := bot.GetAvailableExchanges() if enabledOnly { return exchangeNames } - exchangeNames = append(exchangeNames, Bot.Config.GetDisabledExchanges()...) + exchangeNames = append(exchangeNames, bot.Config.GetDisabledExchanges()...) return exchangeNames } // GetAllActiveTickers returns all enabled exchange tickers -func GetAllActiveTickers() []EnabledExchangeCurrencies { +func (bot *Engine) GetAllActiveTickers() []EnabledExchangeCurrencies { var tickerData []EnabledExchangeCurrencies - exchanges := GetExchanges() + exchanges := bot.GetExchanges() for x := range exchanges { assets := exchanges[x].GetAssetTypes() exchName := exchanges[x].GetName() @@ -736,15 +736,15 @@ func GetAllActiveTickers() []EnabledExchangeCurrencies { } // GetAllEnabledExchangeAccountInfo returns all the current enabled exchanges -func GetAllEnabledExchangeAccountInfo() AllEnabledExchangeAccounts { +func (bot *Engine) GetAllEnabledExchangeAccountInfo() AllEnabledExchangeAccounts { var response AllEnabledExchangeAccounts - exchanges := GetExchanges() + exchanges := bot.GetExchanges() for x := range exchanges { if exchanges[x] != nil && exchanges[x].IsEnabled() { if !exchanges[x].GetAuthenticatedAPISupport(exchange.RestAuthentication) { - if Bot.Settings.Verbose { + if bot.Settings.Verbose { log.Debugf(log.ExchangeSys, - "GetAllEnabledExchangeAccountInfo: Skippping %s due to disabled authenticated API support.\n", + "GetAllEnabledExchangeAccountInfo: Skipping %s due to disabled authenticated API support.\n", exchanges[x].GetName()) } continue diff --git a/engine/helpers_test.go b/engine/helpers_test.go index 30e404d104b..9ad166f9935 100644 --- a/engine/helpers_test.go +++ b/engine/helpers_test.go @@ -29,7 +29,7 @@ var ( helperTestLoaded = false ) -func SetupTestHelpers(t *testing.T) { +func SetupTestHelpers(t *testing.T) *Engine { if !helperTestLoaded { if Bot == nil { Bot = new(Engine) @@ -46,39 +46,40 @@ func SetupTestHelpers(t *testing.T) { helperTestLoaded = true } - if GetExchangeByName(testExchange) == nil { - err := LoadExchange(testExchange, false, nil) + if Bot.GetExchangeByName(testExchange) == nil { + err := Bot.LoadExchange(testExchange, false, nil) if err != nil { t.Fatalf("SetupTest: Failed to load exchange: %s", err) } } - if GetExchangeByName(fakePassExchange) == nil { + if Bot.GetExchangeByName(fakePassExchange) == nil { err := addPassingFakeExchange(testExchange) if err != nil { t.Fatalf("SetupTest: Failed to load exchange: %s", err) } } + return Bot } func TestGetExchangeOTPs(t *testing.T) { - SetupTestHelpers(t) - _, err := GetExchangeOTPs() + bot := SetupTestHelpers(t) + _, err := bot.GetExchangeOTPs() if err == nil { t.Fatal("Expected err with no exchange OTP secrets set") } - bfxCfg, err := Bot.Config.GetExchangeConfig("Bitfinex") + bfxCfg, err := bot.Config.GetExchangeConfig("Bitfinex") if err != nil { t.Fatal(err) } - bCfg, err := Bot.Config.GetExchangeConfig("Bitstamp") + bCfg, err := bot.Config.GetExchangeConfig("Bitstamp") if err != nil { t.Fatal(err) } bfxCfg.API.Credentials.OTPSecret = "JBSWY3DPEHPK3PXP" bCfg.API.Credentials.OTPSecret = "JBSWY3DPEHPK3PXP" - result, err := GetExchangeOTPs() + result, err := bot.GetExchangeOTPs() if err != nil { t.Fatal(err) } @@ -87,7 +88,7 @@ func TestGetExchangeOTPs(t *testing.T) { } bfxCfg.API.Credentials.OTPSecret = "°" - result, err = GetExchangeOTPs() + result, err = bot.GetExchangeOTPs() if err != nil { t.Fatal(err) } @@ -101,19 +102,19 @@ func TestGetExchangeOTPs(t *testing.T) { } func TestGetExchangeoOTPByName(t *testing.T) { - SetupTestHelpers(t) - _, err := GetExchangeoOTPByName("Bitstamp") + bot := SetupTestHelpers(t) + _, err := bot.GetExchangeoOTPByName("Bitstamp") if err == nil { t.Fatal("Expected err with no exchange OTP secrets set") } - bCfg, err := Bot.Config.GetExchangeConfig("Bitstamp") + bCfg, err := bot.Config.GetExchangeConfig("Bitstamp") if err != nil { t.Fatal(err) } bCfg.API.Credentials.OTPSecret = "JBSWY3DPEHPK3PXP" - result, err := GetExchangeoOTPByName("Bitstamp") + result, err := bot.GetExchangeoOTPByName("Bitstamp") if err != nil { t.Fatal(err) } @@ -126,19 +127,19 @@ func TestGetExchangeoOTPByName(t *testing.T) { } func TestGetAuthAPISupportedExchanges(t *testing.T) { - SetupTestHelpers(t) - if result := GetAuthAPISupportedExchanges(); len(result) != 1 { + e := SetupTestHelpers(t) + if result := e.GetAuthAPISupportedExchanges(); len(result) != 1 { t.Fatal("Unexpected result", result) } } func TestIsOnline(t *testing.T) { - SetupTestHelpers(t) - if r := IsOnline(); r { + e := SetupTestHelpers(t) + if r := e.IsOnline(); r { t.Fatal("Unexpected result") } - if err := Bot.ConnectionManager.Start(); err != nil { + if err := e.ConnectionManager.Start(&e.Config.ConnectionMonitor); err != nil { t.Fatal(err) } @@ -149,8 +150,8 @@ func TestIsOnline(t *testing.T) { case <-tick.C: t.Fatal("Test timeout") default: - if IsOnline() { - if err := Bot.ConnectionManager.Stop(); err != nil { + if e.IsOnline() { + if err := e.ConnectionManager.Stop(); err != nil { t.Fatal("unable to shutdown connection manager") } return @@ -160,16 +161,16 @@ func TestIsOnline(t *testing.T) { } func TestGetAvailableExchanges(t *testing.T) { - SetupTestHelpers(t) - if r := len(GetAvailableExchanges()); r == 0 { + e := SetupTestHelpers(t) + if r := len(e.GetAvailableExchanges()); r == 0 { t.Error("Expected len > 0") } } func TestGetSpecificAvailablePairs(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) assetType := asset.Spot - result := GetSpecificAvailablePairs(true, true, true, false, assetType) + result := e.GetSpecificAvailablePairs(true, true, true, false, assetType) btsusd, err := currency.NewPairFromStrings("BTC", "USD") if err != nil { @@ -189,7 +190,7 @@ func TestGetSpecificAvailablePairs(t *testing.T) { t.Fatal("Unexpected result") } - result = GetSpecificAvailablePairs(true, true, false, false, assetType) + result = e.GetSpecificAvailablePairs(true, true, false, false, assetType) if result.Contains(btcusdt, false) { t.Fatal("Unexpected result") @@ -200,7 +201,7 @@ func TestGetSpecificAvailablePairs(t *testing.T) { t.Fatal(err) } - result = GetSpecificAvailablePairs(true, false, false, true, assetType) + result = e.GetSpecificAvailablePairs(true, false, false, true, assetType) if !result.Contains(ltcbtc, false) { t.Fatal("Unexpected result") } @@ -476,14 +477,14 @@ func TestGetRelatableFiatCurrencies(t *testing.T) { } func TestMapCurrenciesByExchange(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) var pairs = []currency.Pair{ currency.NewPair(currency.BTC, currency.USD), currency.NewPair(currency.BTC, currency.EUR), } - result := MapCurrenciesByExchange(pairs, true, asset.Spot) + result := e.MapCurrenciesByExchange(pairs, true, asset.Spot) pairs, ok := result["Bitstamp"] if !ok { t.Fatal("Unexpected result") @@ -495,7 +496,7 @@ func TestMapCurrenciesByExchange(t *testing.T) { } func TestGetExchangeNamesByCurrency(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) assetType := asset.Spot btsusd, err := currency.NewPairFromStrings("BTC", "USD") @@ -513,21 +514,21 @@ func TestGetExchangeNamesByCurrency(t *testing.T) { t.Fatal(err) } - result := GetExchangeNamesByCurrency(btsusd, + result := e.GetExchangeNamesByCurrency(btsusd, true, assetType) if !common.StringDataCompare(result, "Bitstamp") { t.Fatal("Unexpected result") } - result = GetExchangeNamesByCurrency(btcjpy, + result = e.GetExchangeNamesByCurrency(btcjpy, true, assetType) if !common.StringDataCompare(result, "Bitflyer") { t.Fatal("Unexpected result") } - result = GetExchangeNamesByCurrency(blahjpy, + result = e.GetExchangeNamesByCurrency(blahjpy, true, assetType) if len(result) > 0 { @@ -536,9 +537,9 @@ func TestGetExchangeNamesByCurrency(t *testing.T) { } func TestGetSpecificOrderbook(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) - LoadExchange("Bitstamp", false, nil) + e.LoadExchange("Bitstamp", false, nil) var bids []orderbook.Item bids = append(bids, orderbook.Item{Price: 1000, Amount: 1}) @@ -560,7 +561,7 @@ func TestGetSpecificOrderbook(t *testing.T) { t.Fatal(err) } - ob, err := GetSpecificOrderbook(btsusd, "Bitstamp", asset.Spot) + ob, err := e.GetSpecificOrderbook(btsusd, "Bitstamp", asset.Spot) if err != nil { t.Fatal(err) } @@ -574,18 +575,18 @@ func TestGetSpecificOrderbook(t *testing.T) { t.Fatal(err) } - _, err = GetSpecificOrderbook(ethltc, "Bitstamp", asset.Spot) + _, err = e.GetSpecificOrderbook(ethltc, "Bitstamp", asset.Spot) if err == nil { t.Fatal("Unexpected result") } - UnloadExchange("Bitstamp") + e.UnloadExchange("Bitstamp") } func TestGetSpecificTicker(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) - LoadExchange("Bitstamp", false, nil) + e.LoadExchange("Bitstamp", false, nil) p, err := currency.NewPairFromStrings("BTC", "USD") if err != nil { t.Fatal(err) @@ -600,7 +601,7 @@ func TestGetSpecificTicker(t *testing.T) { t.Fatal("ProcessTicker error", err) } - tick, err := GetSpecificTicker(p, "Bitstamp", asset.Spot) + tick, err := e.GetSpecificTicker(p, "Bitstamp", asset.Spot) if err != nil { t.Fatal(err) } @@ -614,12 +615,12 @@ func TestGetSpecificTicker(t *testing.T) { t.Fatal(err) } - _, err = GetSpecificTicker(ethltc, "Bitstamp", asset.Spot) + _, err = e.GetSpecificTicker(ethltc, "Bitstamp", asset.Spot) if err == nil { t.Fatal("Unexpected result") } - UnloadExchange("Bitstamp") + e.UnloadExchange("Bitstamp") } func TestGetCollatedExchangeAccountInfoByCoin(t *testing.T) { @@ -743,27 +744,27 @@ func TestGetExchangeLowestPriceByCurrencyPair(t *testing.T) { } func TestGetCryptocurrenciesByExchange(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) - _, err := GetCryptocurrenciesByExchange("Bitfinex", false, false, asset.Spot) + _, err := e.GetCryptocurrenciesByExchange("Bitfinex", false, false, asset.Spot) if err != nil { t.Fatalf("Err %s", err) } } func TestGetExchangeNames(t *testing.T) { - SetupTestHelpers(t) - if e := GetExchangeNames(true); len(e) == 0 { + bot := SetupTestHelpers(t) + if e := bot.GetExchangeNames(true); len(e) == 0 { t.Error("exchange names should be populated") } - if err := UnloadExchange(testExchange); err != nil { + if err := bot.UnloadExchange(testExchange); err != nil { t.Fatal(err) } - if e := GetExchangeNames(true); common.StringDataCompare(e, testExchange) { + if e := bot.GetExchangeNames(true); common.StringDataCompare(e, testExchange) { t.Error("Bitstamp should be missing") } - if e := GetExchangeNames(false); len(e) != len(Bot.Config.Exchanges) { - t.Errorf("Expected %v Received %v", len(e), len(Bot.Config.Exchanges)) + if e := bot.GetExchangeNames(false); len(e) != len(bot.Config.Exchanges) { + t.Errorf("Expected %v Received %v", len(e), len(bot.Config.Exchanges)) } } diff --git a/engine/orders.go b/engine/orders.go index 15578ca5718..a912c72a1a4 100644 --- a/engine/orders.go +++ b/engine/orders.go @@ -96,7 +96,7 @@ func (o *orderStore) Add(order *order.Detail) error { if order == nil { return errors.New("order store: Order is nil") } - exch := GetExchangeByName(order.Exchange) + exch := Bot.GetExchangeByName(order.Exchange) if exch == nil { return ErrExchangeNotFound } @@ -250,7 +250,7 @@ func (o *orderManager) Cancel(cancel *order.Cancel) error { return errors.New("order id is empty") } - exch := GetExchangeByName(cancel.Exchange) + exch := Bot.GetExchangeByName(cancel.Exchange) if exch == nil { return ErrExchangeNotFound } @@ -307,7 +307,7 @@ func (o *orderManager) Submit(newOrder *order.Submit) (*orderSubmitResponse, err } } - exch := GetExchangeByName(newOrder.Exchange) + exch := Bot.GetExchangeByName(newOrder.Exchange) if exch == nil { return nil, ErrExchangeNotFound } @@ -387,13 +387,13 @@ func (o *orderManager) Submit(newOrder *order.Submit) (*orderSubmitResponse, err } func (o *orderManager) processOrders() { - authExchanges := GetAuthAPISupportedExchanges() + authExchanges := Bot.GetAuthAPISupportedExchanges() for x := range authExchanges { log.Debugf(log.OrderMgr, "Order manager: Processing orders for exchange %v.", authExchanges[x]) - exch := GetExchangeByName(authExchanges[x]) + exch := Bot.GetExchangeByName(authExchanges[x]) supportedAssets := exch.GetAssetTypes() for y := range supportedAssets { pairs, err := exch.GetEnabledPairs(supportedAssets[y]) diff --git a/engine/portfolio.go b/engine/portfolio.go index 3e239b12070..9e9d41ee663 100644 --- a/engine/portfolio.go +++ b/engine/portfolio.go @@ -89,5 +89,5 @@ func (p *portfolioManager) processPortfolio() { key, value) } - SeedExchangeAccountInfo(GetAllEnabledExchangeAccountInfo().Data) + SeedExchangeAccountInfo(Bot.GetAllEnabledExchangeAccountInfo().Data) } diff --git a/engine/restful_router.go b/engine/restful_router.go index 707398eb317..b96480900ee 100644 --- a/engine/restful_router.go +++ b/engine/restful_router.go @@ -31,24 +31,24 @@ func RESTLogger(inner http.Handler, name string) http.Handler { } // StartRESTServer starts a REST server -func StartRESTServer() { - listenAddr := Bot.Config.RemoteControl.DeprecatedRPC.ListenAddress +func StartRESTServer(bot *Engine) { + listenAddr := bot.Config.RemoteControl.DeprecatedRPC.ListenAddress log.Debugf(log.RESTSys, "Deprecated RPC server support enabled. Listen URL: http://%s:%d\n", common.ExtractHost(listenAddr), common.ExtractPort(listenAddr)) - err := http.ListenAndServe(listenAddr, newRouter(true)) + err := http.ListenAndServe(listenAddr, newRouter(bot, true)) if err != nil { log.Errorf(log.RESTSys, "Failed to start deprecated RPC server. Err: %s", err) } } // StartWebsocketServer starts a Websocket server -func StartWebsocketServer() { - listenAddr := Bot.Config.RemoteControl.WebsocketRPC.ListenAddress +func StartWebsocketServer(bot *Engine) { + listenAddr := bot.Config.RemoteControl.WebsocketRPC.ListenAddress log.Debugf(log.RESTSys, "Websocket RPC support enabled. Listen URL: ws://%s:%d/ws\n", common.ExtractHost(listenAddr), common.ExtractPort(listenAddr)) - err := http.ListenAndServe(listenAddr, newRouter(false)) + err := http.ListenAndServe(listenAddr, newRouter(bot, false)) if err != nil { log.Errorf(log.RESTSys, "Failed to start websocket RPC server. Err: %s", err) } @@ -56,15 +56,15 @@ func StartWebsocketServer() { // newRouter takes in the exchange interfaces and returns a new multiplexor // router -func newRouter(isREST bool) *mux.Router { +func newRouter(bot *Engine, isREST bool) *mux.Router { router := mux.NewRouter().StrictSlash(true) var routes []Route var listenAddr string if isREST { - listenAddr = Bot.Config.RemoteControl.DeprecatedRPC.ListenAddress + listenAddr = bot.Config.RemoteControl.DeprecatedRPC.ListenAddress } else { - listenAddr = Bot.Config.RemoteControl.WebsocketRPC.ListenAddress + listenAddr = bot.Config.RemoteControl.WebsocketRPC.ListenAddress } if common.ExtractPort(listenAddr) == 80 { @@ -85,9 +85,9 @@ func newRouter(isREST bool) *mux.Router { {"AllActiveExchangesAndOrderbooks", http.MethodGet, "/exchanges/orderbook/latest/all", RESTGetAllActiveOrderbooks}, } - if Bot.Config.Profiler.Enabled { - if Bot.Config.Profiler.MutexProfileFraction > 0 { - runtime.SetMutexProfileFraction(Bot.Config.Profiler.MutexProfileFraction) + if bot.Config.Profiler.Enabled { + if bot.Config.Profiler.MutexProfileFraction > 0 { + runtime.SetMutexProfileFraction(bot.Config.Profiler.MutexProfileFraction) } log.Debugf(log.RESTSys, "HTTP Go performance profiler (pprof) endpoint enabled: http://%s:%d/debug/pprof/\n", diff --git a/engine/restful_server.go b/engine/restful_server.go index cd6cb7e1af3..792e35ab8ed 100644 --- a/engine/restful_server.go +++ b/engine/restful_server.go @@ -52,13 +52,13 @@ func RESTSaveAllSettings(w http.ResponseWriter, r *http.Request) { RESTfulError(r.Method, err) } - SetupExchanges() + Bot.SetupExchanges() } // GetAllActiveOrderbooks returns all enabled exchanges orderbooks func GetAllActiveOrderbooks() []EnabledExchangeOrderbooks { var orderbookData []EnabledExchangeOrderbooks - exchanges := GetExchanges() + exchanges := Bot.GetExchanges() for x := range exchanges { assets := exchanges[x].GetAssetTypes() exchName := exchanges[x].GetName() @@ -116,7 +116,7 @@ func RESTGetPortfolio(w http.ResponseWriter, r *http.Request) { // RESTGetAllActiveTickers returns all active tickers func RESTGetAllActiveTickers(w http.ResponseWriter, r *http.Request) { var response AllEnabledExchangeCurrencies - response.Data = GetAllActiveTickers() + response.Data = Bot.GetAllActiveTickers() err := RESTfulJSONResponse(w, response) if err != nil { @@ -127,7 +127,7 @@ func RESTGetAllActiveTickers(w http.ResponseWriter, r *http.Request) { // RESTGetAllEnabledAccountInfo via get request returns JSON response of account // info func RESTGetAllEnabledAccountInfo(w http.ResponseWriter, r *http.Request) { - response := GetAllEnabledExchangeAccountInfo() + response := Bot.GetAllEnabledExchangeAccountInfo() err := RESTfulJSONResponse(w, response) if err != nil { RESTfulError(r.Method, err) diff --git a/engine/restful_server_test.go b/engine/restful_server_test.go index 294b831c49d..28bc73d341f 100644 --- a/engine/restful_server_test.go +++ b/engine/restful_server_test.go @@ -44,7 +44,7 @@ func TestConfigAllJsonResponse(t *testing.T) { } func TestInvalidHostRequest(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) req, err := http.NewRequest(http.MethodGet, "/config/all", nil) if err != nil { t.Fatal(err) @@ -52,7 +52,7 @@ func TestInvalidHostRequest(t *testing.T) { req.Host = "invalidsite.com" resp := httptest.NewRecorder() - newRouter(true).ServeHTTP(resp, req) + newRouter(e, true).ServeHTTP(resp, req) if status := resp.Code; status != http.StatusNotFound { t.Errorf("Response returned wrong status code expected %v got %v", http.StatusNotFound, status) @@ -60,7 +60,7 @@ func TestInvalidHostRequest(t *testing.T) { } func TestValidHostRequest(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) req, err := http.NewRequest(http.MethodGet, "/config/all", nil) if err != nil { t.Fatal(err) @@ -68,7 +68,7 @@ func TestValidHostRequest(t *testing.T) { req.Host = "localhost:9050" resp := httptest.NewRecorder() - newRouter(true).ServeHTTP(resp, req) + newRouter(e, true).ServeHTTP(resp, req) if status := resp.Code; status != http.StatusOK { t.Errorf("Response returned wrong status code expected %v got %v", http.StatusOK, status) @@ -76,7 +76,7 @@ func TestValidHostRequest(t *testing.T) { } func TestProfilerEnabledShouldEnableProfileEndPoint(t *testing.T) { - SetupTestHelpers(t) + e := SetupTestHelpers(t) req, err := http.NewRequest(http.MethodGet, "/debug/pprof/", nil) if err != nil { t.Fatal(err) @@ -84,7 +84,7 @@ func TestProfilerEnabledShouldEnableProfileEndPoint(t *testing.T) { req.Host = "localhost:9050" resp := httptest.NewRecorder() - newRouter(true).ServeHTTP(resp, req) + newRouter(e, true).ServeHTTP(resp, req) if status := resp.Code; status != http.StatusNotFound { t.Errorf("Response returned wrong status code expected %v got %v", http.StatusNotFound, status) } @@ -102,7 +102,7 @@ func TestProfilerEnabledShouldEnableProfileEndPoint(t *testing.T) { } resp = httptest.NewRecorder() - newRouter(true).ServeHTTP(resp, req) + newRouter(e, true).ServeHTTP(resp, req) mutexValue = runtime.SetMutexProfileFraction(10) if mutexValue != 5 { t.Fatalf("SetMutexProfileFraction() should be 5 after setup received: %v", mutexValue) diff --git a/engine/routines.go b/engine/routines.go index e2d13354c00..4fdcc2ac953 100644 --- a/engine/routines.go +++ b/engine/routines.go @@ -205,7 +205,7 @@ func WebsocketRoutine() { log.Debugln(log.WebsocketMgr, "Connecting exchange websocket services...") } - exchanges := GetExchanges() + exchanges := Bot.GetExchanges() for i := range exchanges { go func(i int) { if exchanges[i].SupportsWebsocket() { diff --git a/engine/rpcserver.go b/engine/rpcserver.go index 4090925b705..7825de8ae1d 100644 --- a/engine/rpcserver.go +++ b/engine/rpcserver.go @@ -60,9 +60,11 @@ var ( ) // RPCServer struct -type RPCServer struct{} +type RPCServer struct { + *Engine +} -func authenticateClient(ctx context.Context) (context.Context, error) { +func (bot *Engine) authenticateClient(ctx context.Context) (context.Context, error) { md, ok := metadata.FromIncomingContext(ctx) if !ok { return ctx, fmt.Errorf("unable to extract metadata") @@ -85,7 +87,7 @@ func authenticateClient(ctx context.Context) (context.Context, error) { username := strings.Split(string(decoded), ":")[0] password := strings.Split(string(decoded), ":")[1] - if username != Bot.Config.RemoteControl.Username || password != Bot.Config.RemoteControl.Password { + if username != bot.Config.RemoteControl.Username || password != bot.Config.RemoteControl.Password { return ctx, fmt.Errorf("username/password mismatch") } @@ -93,16 +95,16 @@ func authenticateClient(ctx context.Context) (context.Context, error) { } // StartRPCServer starts a gRPC server with TLS auth -func StartRPCServer() { - targetDir := utils.GetTLSDir(Bot.Settings.DataDir) +func StartRPCServer(engine *Engine) { + targetDir := utils.GetTLSDir(engine.Settings.DataDir) err := checkCerts(targetDir) if err != nil { log.Errorf(log.GRPCSys, "gRPC checkCerts failed. err: %s\n", err) return } - log.Debugf(log.GRPCSys, "gRPC server support enabled. Starting gRPC server on https://%v.\n", Bot.Config.RemoteControl.GRPC.ListenAddress) - lis, err := net.Listen("tcp", Bot.Config.RemoteControl.GRPC.ListenAddress) + log.Debugf(log.GRPCSys, "gRPC server support enabled. Starting gRPC server on https://%v.\n", engine.Config.RemoteControl.GRPC.ListenAddress) + lis, err := net.Listen("tcp", engine.Config.RemoteControl.GRPC.ListenAddress) if err != nil { log.Errorf(log.GRPCSys, "gRPC server failed to bind to port: %s", err) return @@ -116,10 +118,10 @@ func StartRPCServer() { opts := []grpc.ServerOption{ grpc.Creds(creds), - grpc.UnaryInterceptor(grpcauth.UnaryServerInterceptor(authenticateClient)), + grpc.UnaryInterceptor(grpcauth.UnaryServerInterceptor(engine.authenticateClient)), } server := grpc.NewServer(opts...) - s := RPCServer{} + s := RPCServer{engine} gctrpc.RegisterGoCryptoTraderServer(server, &s) go func() { @@ -131,16 +133,16 @@ func StartRPCServer() { log.Debugln(log.GRPCSys, "gRPC server started!") - if Bot.Settings.EnableGRPCProxy { - StartRPCRESTProxy() + if s.Settings.EnableGRPCProxy { + s.StartRPCRESTProxy() } } // StartRPCRESTProxy starts a gRPC proxy -func StartRPCRESTProxy() { - log.Debugf(log.GRPCSys, "gRPC proxy server support enabled. Starting gRPC proxy server on http://%v.\n", Bot.Config.RemoteControl.GRPC.GRPCProxyListenAddress) +func (s *RPCServer) StartRPCRESTProxy() { + log.Debugf(log.GRPCSys, "gRPC proxy server support enabled. Starting gRPC proxy server on http://%v.\n", s.Config.RemoteControl.GRPC.GRPCProxyListenAddress) - targetDir := utils.GetTLSDir(Bot.Settings.DataDir) + targetDir := utils.GetTLSDir(s.Settings.DataDir) creds, err := credentials.NewClientTLSFromFile(filepath.Join(targetDir, "cert.pem"), "") if err != nil { log.Errorf(log.GRPCSys, "Unabled to start gRPC proxy. Err: %s\n", err) @@ -150,19 +152,19 @@ func StartRPCRESTProxy() { mux := grpcruntime.NewServeMux() opts := []grpc.DialOption{grpc.WithTransportCredentials(creds), grpc.WithPerRPCCredentials(auth.BasicAuth{ - Username: Bot.Config.RemoteControl.Username, - Password: Bot.Config.RemoteControl.Password, + Username: s.Config.RemoteControl.Username, + Password: s.Config.RemoteControl.Password, }), } err = gctrpc.RegisterGoCryptoTraderHandlerFromEndpoint(context.Background(), - mux, Bot.Config.RemoteControl.GRPC.ListenAddress, opts) + mux, s.Config.RemoteControl.GRPC.ListenAddress, opts) if err != nil { log.Errorf(log.GRPCSys, "Failed to register gRPC proxy. Err: %s\n", err) return } go func() { - if err := http.ListenAndServe(Bot.Config.RemoteControl.GRPC.GRPCProxyListenAddress, mux); err != nil { + if err := http.ListenAndServe(s.Config.RemoteControl.GRPC.GRPCProxyListenAddress, mux); err != nil { log.Errorf(log.GRPCSys, "gRPC proxy failed to server: %s\n", err) return } @@ -173,14 +175,14 @@ func StartRPCRESTProxy() { // GetInfo returns info about the current GoCryptoTrader session func (s *RPCServer) GetInfo(_ context.Context, r *gctrpc.GetInfoRequest) (*gctrpc.GetInfoResponse, error) { - d := time.Since(Bot.Uptime) + d := time.Since(s.Uptime) resp := gctrpc.GetInfoResponse{ Uptime: d.String(), - EnabledExchanges: int64(Bot.Config.CountEnabledExchanges()), - AvailableExchanges: int64(len(Bot.Config.Exchanges)), - DefaultFiatCurrency: Bot.Config.Currency.FiatDisplayCurrency.String(), - DefaultForexProvider: Bot.Config.GetPrimaryForexProvider(), - SubsystemStatus: GetSubsystemsStatus(), + EnabledExchanges: int64(s.Config.CountEnabledExchanges()), + AvailableExchanges: int64(len(s.Config.Exchanges)), + DefaultFiatCurrency: s.Config.Currency.FiatDisplayCurrency.String(), + DefaultForexProvider: s.Config.GetPrimaryForexProvider(), + SubsystemStatus: s.GetSubsystemsStatus(), } endpoints := GetRPCEndpoints() resp.RpcEndpoints = make(map[string]*gctrpc.RPCEndpoint) @@ -195,12 +197,12 @@ func (s *RPCServer) GetInfo(_ context.Context, r *gctrpc.GetInfoRequest) (*gctrp // GetSubsystems returns a list of subsystems and their status func (s *RPCServer) GetSubsystems(_ context.Context, r *gctrpc.GetSubsystemsRequest) (*gctrpc.GetSusbsytemsResponse, error) { - return &gctrpc.GetSusbsytemsResponse{SubsystemsStatus: GetSubsystemsStatus()}, nil + return &gctrpc.GetSusbsytemsResponse{SubsystemsStatus: s.GetSubsystemsStatus()}, nil } // EnableSubsystem enables a engine subsytem func (s *RPCServer) EnableSubsystem(_ context.Context, r *gctrpc.GenericSubsystemRequest) (*gctrpc.GenericResponse, error) { - err := SetSubsystem(r.Subsystem, true) + err := s.SetSubsystem(r.Subsystem, true) if err != nil { return nil, err } @@ -210,7 +212,7 @@ func (s *RPCServer) EnableSubsystem(_ context.Context, r *gctrpc.GenericSubsyste // DisableSubsystem disables a engine subsytem func (s *RPCServer) DisableSubsystem(_ context.Context, r *gctrpc.GenericSubsystemRequest) (*gctrpc.GenericResponse, error) { - err := SetSubsystem(r.Subsystem, false) + err := s.SetSubsystem(r.Subsystem, false) if err != nil { return nil, err } @@ -234,7 +236,7 @@ func (s *RPCServer) GetRPCEndpoints(_ context.Context, r *gctrpc.GetRPCEndpoints // GetCommunicationRelayers returns the status of the engines communication relayers func (s *RPCServer) GetCommunicationRelayers(_ context.Context, r *gctrpc.GetCommunicationRelayersRequest) (*gctrpc.GetCommunicationRelayersResponse, error) { - relayers, err := Bot.CommsManager.GetStatus() + relayers, err := s.CommsManager.GetStatus() if err != nil { return nil, err } @@ -253,13 +255,13 @@ func (s *RPCServer) GetCommunicationRelayers(_ context.Context, r *gctrpc.GetCom // GetExchanges returns a list of exchanges // Param is whether or not you wish to list enabled exchanges func (s *RPCServer) GetExchanges(_ context.Context, r *gctrpc.GetExchangesRequest) (*gctrpc.GetExchangesResponse, error) { - exchanges := strings.Join(GetExchangeNames(r.Enabled), ",") + exchanges := strings.Join(s.GetExchangeNames(r.Enabled), ",") return &gctrpc.GetExchangesResponse{Exchanges: exchanges}, nil } // DisableExchange disables an exchange func (s *RPCServer) DisableExchange(_ context.Context, r *gctrpc.GenericExchangeNameRequest) (*gctrpc.GenericResponse, error) { - err := UnloadExchange(r.Exchange) + err := s.UnloadExchange(r.Exchange) if err != nil { return nil, err } @@ -268,7 +270,7 @@ func (s *RPCServer) DisableExchange(_ context.Context, r *gctrpc.GenericExchange // EnableExchange enables an exchange func (s *RPCServer) EnableExchange(_ context.Context, r *gctrpc.GenericExchangeNameRequest) (*gctrpc.GenericResponse, error) { - err := LoadExchange(r.Exchange, false, nil) + err := s.LoadExchange(r.Exchange, false, nil) if err != nil { return nil, err } @@ -277,20 +279,20 @@ 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.GetExchangeOTPReponse, error) { - result, err := GetExchangeoOTPByName(r.Exchange) + result, err := s.GetExchangeoOTPByName(r.Exchange) return &gctrpc.GetExchangeOTPReponse{OtpCode: result}, err } // GetExchangeOTPCodes retrieves OTP codes for all exchanges which have an // OTP secret installed func (s *RPCServer) GetExchangeOTPCodes(_ context.Context, r *gctrpc.GetExchangeOTPsRequest) (*gctrpc.GetExchangeOTPsResponse, error) { - result, err := GetExchangeOTPs() + result, err := s.GetExchangeOTPs() return &gctrpc.GetExchangeOTPsResponse{OtpCodes: result}, err } // GetExchangeInfo gets info for a specific exchange func (s *RPCServer) GetExchangeInfo(_ context.Context, r *gctrpc.GenericExchangeNameRequest) (*gctrpc.GetExchangeInfoResponse, error) { - exchCfg, err := Bot.Config.GetExchangeConfig(r.Exchange) + exchCfg, err := s.Config.GetExchangeConfig(r.Exchange) if err != nil { return nil, err } @@ -325,7 +327,7 @@ func (s *RPCServer) GetExchangeInfo(_ context.Context, r *gctrpc.GenericExchange // GetTicker returns the ticker for a specified exchange, currency pair and // asset type func (s *RPCServer) GetTicker(_ context.Context, r *gctrpc.GetTickerRequest) (*gctrpc.TickerResponse, error) { - t, err := GetSpecificTicker(currency.Pair{ + t, err := s.GetSpecificTicker(currency.Pair{ Delimiter: r.Pair.Delimiter, Base: currency.NewCode(r.Pair.Base), Quote: currency.NewCode(r.Pair.Quote), @@ -355,7 +357,7 @@ func (s *RPCServer) GetTicker(_ context.Context, r *gctrpc.GetTickerRequest) (*g // GetTickers returns a list of tickers for all enabled exchanges and all // enabled currency pairs func (s *RPCServer) GetTickers(_ context.Context, r *gctrpc.GetTickersRequest) (*gctrpc.GetTickersResponse, error) { - activeTickers := GetAllActiveTickers() + activeTickers := s.GetAllActiveTickers() var tickers []*gctrpc.Tickers for x := range activeTickers { @@ -388,7 +390,7 @@ func (s *RPCServer) GetTickers(_ context.Context, r *gctrpc.GetTickersRequest) ( // GetOrderbook returns an orderbook for a specific exchange, currency pair // and asset type func (s *RPCServer) GetOrderbook(_ context.Context, r *gctrpc.GetOrderbookRequest) (*gctrpc.OrderbookResponse, error) { - ob, err := GetSpecificOrderbook(currency.Pair{ + ob, err := s.GetSpecificOrderbook(currency.Pair{ Delimiter: r.Pair.Delimiter, Base: currency.NewCode(r.Pair.Base), Quote: currency.NewCode(r.Pair.Quote), @@ -479,7 +481,7 @@ func (s *RPCServer) GetOrderbooks(_ context.Context, r *gctrpc.GetOrderbooksRequ // GetAccountInfo returns an account balance for a specific exchange func (s *RPCServer) GetAccountInfo(_ context.Context, r *gctrpc.GetAccountInfoRequest) (*gctrpc.GetAccountInfoResponse, error) { - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -512,7 +514,7 @@ func (s *RPCServer) GetAccountInfoStream(r *gctrpc.GetAccountInfoRequest, stream return errors.New(errExchangeNameUnset) } - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return errExchangeNotLoaded } @@ -595,7 +597,7 @@ func (s *RPCServer) GetConfig(_ context.Context, r *gctrpc.GetConfigRequest) (*g // GetPortfolio returns the portfolio details func (s *RPCServer) GetPortfolio(_ context.Context, r *gctrpc.GetPortfolioRequest) (*gctrpc.GetPortfolioResponse, error) { var addrs []*gctrpc.PortfolioAddress - botAddrs := Bot.Portfolio.Addresses + botAddrs := s.Portfolio.Addresses for x := range botAddrs { addrs = append(addrs, &gctrpc.PortfolioAddress{ @@ -615,7 +617,7 @@ func (s *RPCServer) GetPortfolio(_ context.Context, r *gctrpc.GetPortfolioReques // GetPortfolioSummary returns the portfolio summary func (s *RPCServer) GetPortfolioSummary(_ context.Context, r *gctrpc.GetPortfolioSummaryRequest) (*gctrpc.GetPortfolioSummaryResponse, error) { - result := Bot.Portfolio.GetPortfolioSummary() + result := s.Portfolio.GetPortfolioSummary() var resp gctrpc.GetPortfolioSummaryResponse p := func(coins []portfolio.Coin) []*gctrpc.Coin { @@ -671,7 +673,7 @@ func (s *RPCServer) GetPortfolioSummary(_ context.Context, r *gctrpc.GetPortfoli // AddPortfolioAddress adds an address to the portfolio manager func (s *RPCServer) AddPortfolioAddress(_ context.Context, r *gctrpc.AddPortfolioAddressRequest) (*gctrpc.GenericResponse, error) { - err := Bot.Portfolio.AddAddress(r.Address, + err := s.Portfolio.AddAddress(r.Address, r.Description, currency.NewCode(r.CoinType), r.Balance) @@ -683,7 +685,7 @@ func (s *RPCServer) AddPortfolioAddress(_ context.Context, r *gctrpc.AddPortfoli // RemovePortfolioAddress removes an address from the portfolio manager func (s *RPCServer) RemovePortfolioAddress(_ context.Context, r *gctrpc.RemovePortfolioAddressRequest) (*gctrpc.GenericResponse, error) { - err := Bot.Portfolio.RemoveAddress(r.Address, + err := s.Portfolio.RemoveAddress(r.Address, r.Description, currency.NewCode(r.CoinType)) if err != nil { @@ -694,7 +696,7 @@ func (s *RPCServer) RemovePortfolioAddress(_ context.Context, r *gctrpc.RemovePo // GetForexProviders returns a list of available forex providers func (s *RPCServer) GetForexProviders(_ context.Context, r *gctrpc.GetForexProvidersRequest) (*gctrpc.GetForexProvidersResponse, error) { - providers := Bot.Config.GetForexProviders() + providers := s.Config.GetForexProviders() if len(providers) == 0 { return nil, fmt.Errorf("forex providers is empty") } @@ -751,7 +753,7 @@ func (s *RPCServer) GetForexRates(_ context.Context, r *gctrpc.GetForexRatesRequ // GetOrders returns all open orders, filtered by exchange, currency pair or // asset type func (s *RPCServer) GetOrders(_ context.Context, r *gctrpc.GetOrdersRequest) (*gctrpc.GetOrdersResponse, error) { - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -788,7 +790,7 @@ func (s *RPCServer) GetOrders(_ context.Context, r *gctrpc.GetOrdersRequest) (*g // GetOrder returns order information based on exchange and order ID func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gctrpc.OrderDetails, error) { - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -830,7 +832,7 @@ func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gct // SubmitOrder submits an order specified by exchange, currency pair and asset // type func (s *RPCServer) SubmitOrder(_ context.Context, r *gctrpc.SubmitOrderRequest) (*gctrpc.SubmitOrderResponse, error) { - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -864,7 +866,7 @@ func (s *RPCServer) SubmitOrder(_ context.Context, r *gctrpc.SubmitOrderRequest) // SimulateOrder simulates an order specified by exchange, currency pair and asset // type func (s *RPCServer) SimulateOrder(_ context.Context, r *gctrpc.SimulateOrderRequest) (*gctrpc.SimulateOrderResponse, error) { - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -905,7 +907,7 @@ func (s *RPCServer) SimulateOrder(_ context.Context, r *gctrpc.SimulateOrderRequ // WhaleBomb finds the amount required to reach a specific price target for a given exchange, pair // and asset type func (s *RPCServer) WhaleBomb(_ context.Context, r *gctrpc.WhaleBombRequest) (*gctrpc.SimulateOrderResponse, error) { - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -946,7 +948,7 @@ func (s *RPCServer) WhaleBomb(_ context.Context, r *gctrpc.WhaleBombRequest) (*g // CancelOrder cancels an order specified by exchange, currency pair and asset // type func (s *RPCServer) CancelOrder(_ context.Context, r *gctrpc.CancelOrderRequest) (*gctrpc.GenericResponse, error) { - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -1013,31 +1015,31 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } - result, err := GetCryptocurrencyDepositAddressesByExchange(r.Exchange) + result, err := s.GetCryptocurrencyDepositAddressesByExchange(r.Exchange) return &gctrpc.GetCryptocurrencyDepositAddressesResponse{Addresses: result}, err } // GetCryptocurrencyDepositAddress returns a cryptocurrency deposit address // specified by exchange and cryptocurrency func (s *RPCServer) GetCryptocurrencyDepositAddress(_ context.Context, r *gctrpc.GetCryptocurrencyDepositAddressRequest) (*gctrpc.GetCryptocurrencyDepositAddressResponse, error) { - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } - addr, err := GetExchangeCryptocurrencyDepositAddress(r.Exchange, "", currency.NewCode(r.Cryptocurrency)) + addr, err := s.GetExchangeCryptocurrencyDepositAddress(r.Exchange, "", currency.NewCode(r.Cryptocurrency)) return &gctrpc.GetCryptocurrencyDepositAddressResponse{Address: addr}, err } // WithdrawCryptocurrencyFunds withdraws cryptocurrency funds specified by // exchange func (s *RPCServer) WithdrawCryptocurrencyFunds(_ context.Context, r *gctrpc.WithdrawCryptoRequest) (*gctrpc.WithdrawResponse, error) { - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -1067,7 +1069,7 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -1107,7 +1109,7 @@ func (s *RPCServer) WithdrawFiatFunds(_ context.Context, r *gctrpc.WithdrawFiatR // WithdrawalEventByID returns previous withdrawal request details func (s *RPCServer) WithdrawalEventByID(_ context.Context, r *gctrpc.WithdrawalEventByIDRequest) (*gctrpc.WithdrawalEventByIDResponse, error) { - if !Bot.Config.Database.Enabled { + if !s.Config.Database.Enabled { return nil, database.ErrDatabaseSupportDisabled } v, err := WithdrawalEventByID(r.Id) @@ -1169,7 +1171,7 @@ func (s *RPCServer) WithdrawalEventByID(_ context.Context, r *gctrpc.WithdrawalE // WithdrawalEventsByExchange returns previous withdrawal request details by exchange func (s *RPCServer) WithdrawalEventsByExchange(_ context.Context, r *gctrpc.WithdrawalEventsByExchangeRequest) (*gctrpc.WithdrawalEventsByExchangeResponse, error) { - if !Bot.Config.Database.Enabled { + if !s.Config.Database.Enabled { return nil, database.ErrDatabaseSupportDisabled } if r.Id == "" { @@ -1239,7 +1241,7 @@ func (s *RPCServer) SetLoggerDetails(_ context.Context, r *gctrpc.SetLoggerDetai // GetExchangePairs returns a list of exchange supported assets and related pairs func (s *RPCServer) GetExchangePairs(_ context.Context, r *gctrpc.GetExchangePairsRequest) (*gctrpc.GetExchangePairsResponse, error) { - exchCfg, err := Bot.Config.GetExchangeConfig(r.Exchange) + exchCfg, err := s.Config.GetExchangeConfig(r.Exchange) if err != nil { return nil, err } @@ -1272,7 +1274,7 @@ func (s *RPCServer) GetExchangePairs(_ context.Context, r *gctrpc.GetExchangePai // SetExchangePair enables/disabled the specified pair(s) on an exchange func (s *RPCServer) SetExchangePair(_ context.Context, r *gctrpc.SetExchangePairRequest) (*gctrpc.GenericResponse, error) { - exchCfg, err := Bot.Config.GetExchangeConfig(r.Exchange) + exchCfg, err := s.Config.GetExchangeConfig(r.Exchange) if err != nil { return nil, err } @@ -1287,7 +1289,7 @@ func (s *RPCServer) SetExchangePair(_ context.Context, r *gctrpc.SetExchangePair a := asset.Item(r.AssetType) - exch := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -1297,7 +1299,7 @@ func (s *RPCServer) SetExchangePair(_ context.Context, r *gctrpc.SetExchangePair return nil, errExchangeBaseNotFound } - pairFmt, err := Bot.Config.GetPairFormat(r.Exchange, a) + pairFmt, err := s.Config.GetPairFormat(r.Exchange, a) if err != nil { return nil, err } @@ -1636,7 +1638,7 @@ func (s *RPCServer) GetHistoricCandles(_ context.Context, req *gctrpc.GetHistori time.Unix(req.End, 0), ) } else { - exchangeEngine := GetExchangeByName(req.Exchange) + exchangeEngine := s.GetExchangeByName(req.Exchange) if exchangeEngine == nil { return nil, errors.New("Exchange " + req.Exchange + " not found") } @@ -1984,12 +1986,12 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } - exchCfg, err := Bot.Config.GetExchangeConfig(r.Exchange) + exchCfg, err := s.Config.GetExchangeConfig(r.Exchange) if err != nil { return nil, err } @@ -2018,12 +2020,12 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } - exchCfg, err := Bot.Config.GetExchangeConfig(r.Exchange) + exchCfg, err := s.Config.GetExchangeConfig(r.Exchange) if err != nil { return nil, err } @@ -2066,7 +2068,7 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -2097,7 +2099,7 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -2109,7 +2111,7 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -2131,7 +2133,7 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -2141,7 +2143,7 @@ func (s *RPCServer) WebsocketSetEnabled(_ context.Context, r *gctrpc.WebsocketSe return nil, fmt.Errorf("websocket not supported for exchange %s", r.Exchange) } - exchCfg, err := Bot.Config.GetExchangeConfig(r.Exchange) + exchCfg, err := s.Config.GetExchangeConfig(r.Exchange) if err != nil { return nil, err } @@ -2166,7 +2168,7 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -2197,7 +2199,7 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } @@ -2219,7 +2221,7 @@ 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 := GetExchangeByName(r.Exchange) + exch := s.GetExchangeByName(r.Exchange) if exch == nil { return nil, errExchangeNotLoaded } diff --git a/engine/syncer.go b/engine/syncer.go index bf4f8e8db91..d18a83a3b2e 100644 --- a/engine/syncer.go +++ b/engine/syncer.go @@ -293,7 +293,7 @@ func (e *ExchangeCurrencyPairSyncer) worker() { defer cleanup() for atomic.LoadInt32(&e.shutdown) != 1 { - exchanges := GetExchanges() + exchanges := Bot.GetExchanges() for x := range exchanges { exchangeName := exchanges[x].GetName() assetTypes := exchanges[x].GetAssetTypes() @@ -502,7 +502,7 @@ func (e *ExchangeCurrencyPairSyncer) worker() { // Start starts an exchange currency pair syncer func (e *ExchangeCurrencyPairSyncer) Start() { log.Debugln(log.SyncMgr, "Exchange CurrencyPairSyncer started.") - exchanges := GetExchanges() + exchanges := Bot.GetExchanges() for x := range exchanges { exchangeName := exchanges[x].GetName() supportsWebsocket := exchanges[x].SupportsWebsocket() diff --git a/engine/syncer_test.go b/engine/syncer_test.go index 8546e21ec7c..7a37dcf7578 100644 --- a/engine/syncer_test.go +++ b/engine/syncer_test.go @@ -23,7 +23,7 @@ func TestNewCurrencyPairSyncer(t *testing.T) { Bot.Settings.Verbose = true Bot.Settings.EnableExchangeWebsocketSupport = true - SetupExchanges() + Bot.SetupExchanges() if err != nil { t.Log("failed to start exchange syncer") diff --git a/engine/websocket.go b/engine/websocket.go index 99cef467fc6..78ba3d81b61 100644 --- a/engine/websocket.go +++ b/engine/websocket.go @@ -317,13 +317,13 @@ func wsSaveConfig(client *WebsocketClient, data interface{}) error { return err } - SetupExchanges() + Bot.SetupExchanges() wsResp.Data = WebsocketResponseSuccess return client.SendWebsocketMessage(wsResp) } func wsGetAccountInfo(client *WebsocketClient, data interface{}) error { - accountInfo := GetAllEnabledExchangeAccountInfo() + accountInfo := Bot.GetAllEnabledExchangeAccountInfo() wsResp := WebsocketEventResponse{ Event: "GetAccountInfo", Data: accountInfo, @@ -335,7 +335,7 @@ func wsGetTickers(client *WebsocketClient, data interface{}) error { wsResp := WebsocketEventResponse{ Event: "GetTickers", } - wsResp.Data = GetAllActiveTickers() + wsResp.Data = Bot.GetAllActiveTickers() return client.SendWebsocketMessage(wsResp) } @@ -356,7 +356,7 @@ func wsGetTicker(client *WebsocketClient, data interface{}) error { return err } - result, err := GetSpecificTicker(p, + result, err := Bot.GetSpecificTicker(p, tickerReq.Exchange, asset.Item(tickerReq.AssetType)) @@ -394,7 +394,7 @@ func wsGetOrderbook(client *WebsocketClient, data interface{}) error { return err } - result, err := GetSpecificOrderbook(p, + result, err := Bot.GetSpecificOrderbook(p, orderbookReq.Exchange, asset.Item(orderbookReq.AssetType)) if err != nil { diff --git a/engine/withdraw.go b/engine/withdraw.go index 3f5c606328f..df1a13091d9 100644 --- a/engine/withdraw.go +++ b/engine/withdraw.go @@ -38,7 +38,7 @@ func SubmitWithdrawal(exchName string, req *withdraw.Request) (*withdraw.Respons return nil, err } - exch := GetExchangeByName(exchName) + exch := Bot.GetExchangeByName(exchName) if exch == nil { return nil, ErrExchangeNotFound } diff --git a/gctscript/wrappers/gct/exchange/exchange.go b/gctscript/wrappers/gct/exchange/exchange.go index 64300a2c171..1ba5397fe26 100644 --- a/gctscript/wrappers/gct/exchange/exchange.go +++ b/gctscript/wrappers/gct/exchange/exchange.go @@ -25,12 +25,12 @@ type Exchange struct{} // Exchanges returns slice of all current exchanges func (e Exchange) Exchanges(enabledOnly bool) []string { - return engine.GetExchangeNames(enabledOnly) + return engine.Bot.GetExchangeNames(enabledOnly) } // GetExchange returns IBotExchange for exchange or error if exchange is not found func (e Exchange) GetExchange(exch string) (exchange.IBotExchange, error) { - ex := engine.GetExchangeByName(exch) + ex := engine.Bot.GetExchangeByName(exch) if ex == nil { return nil, fmt.Errorf("%v exchange not found", exch) } @@ -50,7 +50,7 @@ func (e Exchange) IsEnabled(exch string) bool { // Orderbook returns current orderbook requested exchange, pair and asset func (e Exchange) Orderbook(exch string, pair currency.Pair, item asset.Item) (*orderbook.Base, error) { - return engine.GetSpecificOrderbook(pair, exch, item) + return engine.Bot.GetSpecificOrderbook(pair, exch, item) } // Ticker returns ticker for provided currency pair & asset type @@ -166,7 +166,7 @@ func (e Exchange) WithdrawalFiatFunds(exch, bankAccountID string, request *withd } } - otp, err := engine.GetExchangeoOTPByName(exch) + otp, err := engine.Bot.GetExchangeoOTPByName(exch) if err == nil { otpValue, errParse := strconv.ParseInt(otp, 10, 64) if errParse != nil { @@ -200,7 +200,7 @@ func (e Exchange) WithdrawalCryptoFunds(exch string, request *withdraw.Request) return "", err } - otp, err := engine.GetExchangeoOTPByName(exch) + otp, err := engine.Bot.GetExchangeoOTPByName(exch) if err == nil { v, errParse := strconv.ParseInt(otp, 10, 64) if errParse != nil { diff --git a/gctscript/wrappers/gct/exchange/exchange_test.go b/gctscript/wrappers/gct/exchange/exchange_test.go index 16a4cb69c05..77161f0f8af 100644 --- a/gctscript/wrappers/gct/exchange/exchange_test.go +++ b/gctscript/wrappers/gct/exchange/exchange_test.go @@ -195,7 +195,7 @@ func cleanup() { } func configureExchangeKeys() bool { - ex := engine.GetExchangeByName(exchName).GetBase() + ex := engine.Bot.GetExchangeByName(exchName).GetBase() ex.SetAPIKeys(exchAPIKEY, exchAPISECRET, exchClientID) ex.SkipAuthCheck = true return ex.ValidateAPICredentials()