accounts: Move to instance methods, fix races and isolate tests (#1923)

* Bybit: Fix race in TestUpdateAccountInfo and  TestWSHandleData

* DriveBy rename TestWSHandleData
* This doesn't address running with -race=2+ due to the singleton

* Accounts: Add account.GetService()

* exchange: Assertify TestSetupDefaults

* Exchanges: Add account.Service override for testing

* Exchanges: Remove duplicate IsWebsocketEnabled test from TestSetupDefaults

* Dispatch: Replace nil checks with NilGuard

* Engine: Remove deprecated printAccountHoldingsChangeSummary

* Dispatcher: Add EnsureRunning method

* Accounts: Move singleton accounts service to exchange Accounts

* Move singleton accounts service to exchange Accounts

This maintains the concept of a global store, whilst allowing exchanges
to override it when needed, particularly for testing.

APIServer:

* Remove getAllActiveAccounts from apiserver

Deprecated apiserver only thing using this, so remove it instead of
updating it

* Update comment for UpdateAccountBalances everywhere

* Docs: Add punctuation to function comments

* Bybit: Coverage for wsProcessWalletPushData Save
This commit is contained in:
Gareth Kirwan
2025-10-28 09:52:45 +07:00
committed by GitHub
parent bda9bbec66
commit 73e200e4e7
140 changed files with 3515 additions and 4025 deletions

View File

@@ -20,9 +20,10 @@ import (
"github.com/thrasher-corp/gocryptotrader/common/key"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/dispatch"
"github.com/thrasher-corp/gocryptotrader/exchange/accounts"
"github.com/thrasher-corp/gocryptotrader/exchange/order/limits"
"github.com/thrasher-corp/gocryptotrader/exchange/websocket"
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/collateral"
"github.com/thrasher-corp/gocryptotrader/exchanges/currencystate"
@@ -264,8 +265,7 @@ func (b *Base) GetClientBankAccounts(exchangeName, withdrawalCurrency string) (*
return cfg.GetClientBankAccounts(exchangeName, withdrawalCurrency)
}
// GetExchangeBankAccounts returns banking details associated with an
// exchange for funding purposes
// GetExchangeBankAccounts returns banking details associated with an exchange for funding purposes
func (b *Base) GetExchangeBankAccounts(id, depositCurrency string) (*banking.Account, error) {
cfg := config.GetConfig()
return cfg.GetExchangeBankAccounts(b.Name, id, depositCurrency)
@@ -600,7 +600,15 @@ func (b *Base) SetupDefaults(exch *config.Exchange) error {
log.Warnf(log.ExchangeSys, "%s orderbook verification has been bypassed via config.", b.Name)
}
if b.Accounts == nil {
var err error
if b.Accounts, err = accounts.GetStore().GetExchangeAccounts(b); err != nil {
return err
}
}
b.ValidateOrderbook = !exch.Orderbook.VerificationBypass
b.States = currencystate.NewCurrencyStates()
return nil
@@ -1910,14 +1918,24 @@ func (b *Base) GetCachedOrderbook(p currency.Pair, assetType asset.Item) (*order
return orderbook.Get(b.Name, p, assetType)
}
// GetCachedAccountInfo retrieves balances for all enabled currencies
// NOTE: UpdateAccountInfo method must be called first to update the account info map
func (b *Base) GetCachedAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) {
// GetCachedSubAccounts retrieves all cached SubAccounts, filtered by credentials and asset
// NOTE: Accounts.Save method should be called first to populate the local cache
func (b *Base) GetCachedSubAccounts(ctx context.Context, assetType asset.Item) (accounts.SubAccounts, error) {
creds, err := b.GetCredentials(ctx)
if err != nil {
return account.Holdings{}, err
return nil, err
}
return account.GetHoldings(b.Name, creds, assetType)
return b.Accounts.SubAccounts(creds, assetType)
}
// GetCachedCurrencyBalances retrieves cached balances for all SubAccounts grouped by currency
// NOTE: Accounts.Save method should be called first to populate the local cache
func (b *Base) GetCachedCurrencyBalances(ctx context.Context, assetType asset.Item) (accounts.CurrencyBalances, error) {
creds, err := b.GetCredentials(ctx)
if err != nil {
return nil, err
}
return b.Accounts.CurrencyBalances(creds, assetType)
}
// GetOrderExecutionLimits returns a limit based on the exchange, asset and pair from storage
@@ -1966,3 +1984,8 @@ func (b *Base) MessageID() string {
func (b *Base) MessageSequence() int64 {
return b.messageSequence.IncrementAndGet()
}
// SubscribeAccountBalances returns a pipe to stream account holding updates
func (b *Base) SubscribeAccountBalances() (dispatch.Pipe, error) {
return b.Accounts.Subscribe()
}