mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
Engine changes
Add addr helpers (will be split off into own package) Engine status updates (log and data dir display) Use GetPairFormat for various exchanges instead of calling the config QA fixes Implement GCTRPC exchange deposit address handling
This commit is contained in:
100
engine/addr_helpers.go
Normal file
100
engine/addr_helpers.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
)
|
||||
|
||||
// DepositAddressStore stores a list of exchange deposit addresses
|
||||
type DepositAddressStore struct {
|
||||
m sync.Mutex
|
||||
Store map[string]map[string]string
|
||||
}
|
||||
|
||||
// DepositAddressManager manages the exchange deposit address store
|
||||
type DepositAddressManager struct {
|
||||
Store DepositAddressStore
|
||||
}
|
||||
|
||||
// vars related to the deposit address helpers
|
||||
var (
|
||||
ErrDepositAddressStoreIsNil = errors.New("deposit address store is nil")
|
||||
ErrDepositAddressNotFound = errors.New("deposit address does not exist")
|
||||
)
|
||||
|
||||
// Seed seeds the deposit address store
|
||||
func (d *DepositAddressStore) Seed(coinData map[string]map[string]string) {
|
||||
d.m.Lock()
|
||||
defer d.m.Unlock()
|
||||
if d.Store == nil {
|
||||
d.Store = make(map[string]map[string]string)
|
||||
}
|
||||
|
||||
for k, v := range coinData {
|
||||
r := make(map[string]string)
|
||||
for w, x := range v {
|
||||
r[strings.ToUpper(w)] = x
|
||||
}
|
||||
d.Store[strings.ToUpper(k)] = r
|
||||
}
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address based on the specified item
|
||||
func (d *DepositAddressStore) GetDepositAddress(exchName string, item currency.Code) (string, error) {
|
||||
d.m.Lock()
|
||||
defer d.m.Unlock()
|
||||
|
||||
if len(d.Store) == 0 {
|
||||
return "", ErrDepositAddressStoreIsNil
|
||||
}
|
||||
|
||||
r, ok := d.Store[strings.ToUpper(exchName)]
|
||||
if !ok {
|
||||
return "", ErrExchangeNotFound
|
||||
}
|
||||
|
||||
addr, ok := r[strings.ToUpper(item.String())]
|
||||
if !ok {
|
||||
return "", ErrDepositAddressNotFound
|
||||
}
|
||||
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
// GetDepositAddresses returns a list of stored deposit addresses
|
||||
func (d *DepositAddressStore) GetDepositAddresses(exchName string) (map[string]string, error) {
|
||||
d.m.Lock()
|
||||
defer d.m.Unlock()
|
||||
|
||||
if len(d.Store) == 0 {
|
||||
return nil, ErrDepositAddressStoreIsNil
|
||||
}
|
||||
|
||||
r, ok := d.Store[strings.ToUpper(exchName)]
|
||||
if !ok {
|
||||
return nil, ErrDepositAddressNotFound
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// GetDepositAddressByExchange returns a deposit address for the specified exchange and cryptocurrency
|
||||
// if it exists
|
||||
func (d *DepositAddressManager) GetDepositAddressByExchange(exchName string, currencyItem currency.Code) (string, error) {
|
||||
return d.Store.GetDepositAddress(exchName, currencyItem)
|
||||
}
|
||||
|
||||
// GetDepositAddressesByExchange returns a list of cryptocurrency addresses for the specified
|
||||
// exchange if they exist
|
||||
func (d *DepositAddressManager) GetDepositAddressesByExchange(exchName string) (map[string]string, error) {
|
||||
return d.Store.GetDepositAddresses(exchName)
|
||||
}
|
||||
|
||||
// Sync synchronises all deposit addresses
|
||||
func (d *DepositAddressManager) Sync() {
|
||||
result := GetExchangeCryptocurrencyDepositAddresses()
|
||||
d.Store.Seed(result)
|
||||
}
|
||||
64
engine/addr_helpers_test.go
Normal file
64
engine/addr_helpers_test.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
)
|
||||
|
||||
const (
|
||||
testBTCAddress = "1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX"
|
||||
)
|
||||
|
||||
func TestSeed(t *testing.T) {
|
||||
var d DepositAddressStore
|
||||
u := map[string]map[string]string{
|
||||
"BITSTAMP": map[string]string{
|
||||
"BTC": testBTCAddress,
|
||||
},
|
||||
}
|
||||
|
||||
d.Seed(u)
|
||||
r, err := d.GetDepositAddress("BITSTAMP", currency.BTC)
|
||||
if err != nil {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
|
||||
if r != testBTCAddress {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
var d DepositAddressStore
|
||||
_, err := d.GetDepositAddress("", currency.BTC)
|
||||
if err != ErrDepositAddressStoreIsNil {
|
||||
t.Error("non-error on non-existent exchange")
|
||||
}
|
||||
|
||||
d.Store = map[string]map[string]string{
|
||||
"BITSTAMP": map[string]string{
|
||||
"BTC": testBTCAddress,
|
||||
},
|
||||
}
|
||||
|
||||
_, err = d.GetDepositAddress("", currency.BTC)
|
||||
if err != ErrExchangeNotFound {
|
||||
t.Error("non-error on non-existent exchange")
|
||||
}
|
||||
|
||||
var r string
|
||||
r, err = d.GetDepositAddress("BiTStAmP", currency.NewCode("bTC"))
|
||||
if err != nil {
|
||||
t.Error("unexpected err: ", err)
|
||||
}
|
||||
|
||||
if r != testBTCAddress {
|
||||
t.Error("unexpected BTC address: ", r)
|
||||
}
|
||||
|
||||
_, err = d.GetDepositAddress("BiTStAmP", currency.LTC)
|
||||
if err != ErrDepositAddressNotFound {
|
||||
t.Error("unexpected err: ", err)
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -25,20 +24,20 @@ import (
|
||||
// Engine contains configuration, portfolio, exchange & ticker data and is the
|
||||
// overarching type across this code base.
|
||||
type Engine struct {
|
||||
Config *config.Config
|
||||
Portfolio *portfolio.Base
|
||||
Exchanges []exchange.IBotExchange
|
||||
ExchangeCurrencyPairManager *ExchangeCurrencyPairSyncer
|
||||
NTPManager ntpManager
|
||||
ConnectionManager connectionManager
|
||||
OrderManager orderManager
|
||||
PortfolioManager portfolioManager
|
||||
CommsManager commsManager
|
||||
Shutdown chan struct{}
|
||||
Settings Settings
|
||||
CryptocurrencyDepositAddresses map[string]map[string]string
|
||||
Uptime time.Time
|
||||
ServicesWG sync.WaitGroup
|
||||
Config *config.Config
|
||||
Portfolio *portfolio.Base
|
||||
Exchanges []exchange.IBotExchange
|
||||
ExchangeCurrencyPairManager *ExchangeCurrencyPairSyncer
|
||||
NTPManager ntpManager
|
||||
ConnectionManager connectionManager
|
||||
OrderManager orderManager
|
||||
PortfolioManager portfolioManager
|
||||
CommsManager commsManager
|
||||
DepositAddressManager *DepositAddressManager
|
||||
Shutdown chan struct{}
|
||||
Settings Settings
|
||||
Uptime time.Time
|
||||
ServicesWG sync.WaitGroup
|
||||
}
|
||||
|
||||
// Vars for engine
|
||||
@@ -62,8 +61,6 @@ func New() (*Engine, error) {
|
||||
return nil, fmt.Errorf("failed to load config. Err: %s", err)
|
||||
}
|
||||
|
||||
b.CryptocurrencyDepositAddresses = make(map[string]map[string]string)
|
||||
|
||||
return &b, nil
|
||||
}
|
||||
|
||||
@@ -75,7 +72,7 @@ func NewFromSettings(settings *Settings) (*Engine, error) {
|
||||
|
||||
var b Engine
|
||||
b.Config = &config.Cfg
|
||||
log.Debugf("Loading config file %s..\n", settings.ConfigFile)
|
||||
log.Debugf("Loading config file %s...\n", settings.ConfigFile)
|
||||
err := b.Config.LoadConfig(settings.ConfigFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load config. Err: %s", err)
|
||||
@@ -93,8 +90,11 @@ func NewFromSettings(settings *Settings) (*Engine, error) {
|
||||
|
||||
b.Settings.ConfigFile = settings.ConfigFile
|
||||
b.Settings.DataDir = settings.DataDir
|
||||
b.Settings.LogFile = path.Join(log.LogPath, log.Logger.File)
|
||||
b.CryptocurrencyDepositAddresses = make(map[string]map[string]string)
|
||||
|
||||
if *log.Logger.Enabled {
|
||||
b.Settings.LogFile = log.LogPath
|
||||
log.Debugf("Using log file: %s.\n", log.LogPath)
|
||||
}
|
||||
|
||||
err = utils.AdjustGoMaxProcs(settings.GoMaxProcs)
|
||||
if err != nil {
|
||||
@@ -102,9 +102,7 @@ func NewFromSettings(settings *Settings) (*Engine, error) {
|
||||
}
|
||||
|
||||
b.handleInterrupt()
|
||||
|
||||
ValidateSettings(&b, settings)
|
||||
|
||||
return &b, nil
|
||||
}
|
||||
|
||||
@@ -157,6 +155,7 @@ func ValidateSettings(b *Engine, s *Settings) {
|
||||
b.Settings.EnableNTPClient = s.EnableNTPClient
|
||||
b.Settings.EnableOrderManager = s.EnableOrderManager
|
||||
b.Settings.EnableExchangeSyncManager = s.EnableExchangeSyncManager
|
||||
b.Settings.EnableDepositAddressManager = s.EnableDepositAddressManager
|
||||
b.Settings.EnableTickerSyncing = s.EnableTickerSyncing
|
||||
b.Settings.EnableOrderbookSyncing = s.EnableOrderbookSyncing
|
||||
b.Settings.EnableExchangeAutoPairUpdates = s.EnableExchangeAutoPairUpdates
|
||||
@@ -228,6 +227,7 @@ func PrintSettings(s *Settings) {
|
||||
log.Debugf("\t Event manager sleep delay: %v", s.EventManagerDelay)
|
||||
log.Debugf("\t Enable order manager: %v", s.EnableOrderManager)
|
||||
log.Debugf("\t Enable exchange sync manager: %v", s.EnableExchangeSyncManager)
|
||||
log.Debugf("\t Enable deposit address manager: %v\n", s.EnableDepositAddressManager)
|
||||
log.Debugf("\t Enable ticker syncing: %v", s.EnableTickerSyncing)
|
||||
log.Debugf("\t Enable orderbook syncing: %v", s.EnableOrderbookSyncing)
|
||||
log.Debugf("\t Enable websocket routine: %v\n", s.EnableWebsocketRoutine)
|
||||
@@ -277,6 +277,7 @@ func (e *Engine) Start() {
|
||||
|
||||
e.Uptime = time.Now()
|
||||
log.Debugf("Bot '%s' started.\n", e.Config.Name)
|
||||
log.Debugf("Using data dir: %s\n", e.Settings.DataDir)
|
||||
|
||||
enabledExchanges := e.Config.CountEnabledExchanges()
|
||||
if e.Settings.EnableAllExchanges {
|
||||
@@ -331,8 +332,6 @@ func (e *Engine) Start() {
|
||||
log.Warn("currency updater system failed to start", err)
|
||||
}
|
||||
|
||||
e.CryptocurrencyDepositAddresses = GetExchangeCryptocurrencyDepositAddresses()
|
||||
|
||||
if e.Settings.EnableGRPC {
|
||||
go StartRPCServer()
|
||||
}
|
||||
@@ -352,6 +351,11 @@ func (e *Engine) Start() {
|
||||
}
|
||||
}
|
||||
|
||||
if e.Settings.EnableDepositAddressManager {
|
||||
e.DepositAddressManager = new(DepositAddressManager)
|
||||
e.DepositAddressManager.Sync()
|
||||
}
|
||||
|
||||
if e.Settings.EnableOrderManager {
|
||||
if err = e.OrderManager.Start(); err != nil {
|
||||
log.Errorf("Order manager unable to start: %v", err)
|
||||
|
||||
@@ -21,6 +21,7 @@ type Settings struct {
|
||||
EnableDeprecatedRPC bool
|
||||
EnableCommsRelayer bool
|
||||
EnableExchangeSyncManager bool
|
||||
EnableDepositAddressManager bool
|
||||
EnableTickerSyncing bool
|
||||
EnableOrderbookSyncing bool
|
||||
EnableEventManager bool
|
||||
|
||||
@@ -629,15 +629,34 @@ func GetCryptocurrenciesByExchange(exchangeName string, enabledExchangesOnly, en
|
||||
return cryptocurrencies, nil
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
result := GetExchangeCryptocurrencyDepositAddresses()
|
||||
r, ok := result[exchName]
|
||||
if !ok {
|
||||
return nil, ErrExchangeNotFound
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// GetExchangeCryptocurrencyDepositAddress returns the cryptocurrency deposit address for a particular
|
||||
// exchange
|
||||
func GetExchangeCryptocurrencyDepositAddress(exchName string, item currency.Code) (string, error) {
|
||||
func GetExchangeCryptocurrencyDepositAddress(exchName, accountID string, item currency.Code) (string, error) {
|
||||
if Bot.DepositAddressManager != nil {
|
||||
return Bot.DepositAddressManager.GetDepositAddressByExchange(exchName, item)
|
||||
}
|
||||
|
||||
exch := GetExchangeByName(exchName)
|
||||
if exch == nil {
|
||||
return "", ErrExchangeNotFound
|
||||
}
|
||||
|
||||
return exch.GetDepositAddress(item, "")
|
||||
return exch.GetDepositAddress(item, accountID)
|
||||
}
|
||||
|
||||
// GetExchangeCryptocurrencyDepositAddresses obtains an exchanges deposit cryptocurrency list
|
||||
@@ -649,7 +668,6 @@ func GetExchangeCryptocurrencyDepositAddresses() map[string]map[string]string {
|
||||
continue
|
||||
}
|
||||
exchName := Bot.Exchanges[x].GetName()
|
||||
|
||||
if !Bot.Exchanges[x].GetAuthenticatedAPISupport(exchange.RestAuthentication) {
|
||||
if Bot.Settings.Verbose {
|
||||
log.Debugf("GetExchangeCryptocurrencyDepositAddresses: Skippping %s due to disabled authenticated API support.", exchName)
|
||||
@@ -679,40 +697,18 @@ func GetExchangeCryptocurrencyDepositAddresses() map[string]map[string]string {
|
||||
return result
|
||||
}
|
||||
|
||||
// GetDepositAddressByExchange returns a deposit address for the specified exchange and cryptocurrency
|
||||
// if it exists
|
||||
func GetDepositAddressByExchange(exchName string, currencyItem currency.Code) string {
|
||||
for x, y := range Bot.CryptocurrencyDepositAddresses {
|
||||
if exchName == x {
|
||||
addr, ok := y[currencyItem.String()]
|
||||
if ok {
|
||||
return addr
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetDepositAddressesByExchange returns a list of cryptocurrency addresses for the specified
|
||||
// exchange if they exist
|
||||
func GetDepositAddressesByExchange(exchName string) map[string]string {
|
||||
for x, y := range Bot.CryptocurrencyDepositAddresses {
|
||||
if exchName == x {
|
||||
return y
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithdrawCryptocurrencyFundsByExchange withdraws the desired cryptocurrency and amount to a desired cryptocurrency address
|
||||
func WithdrawCryptocurrencyFundsByExchange(exchName string) (string, error) {
|
||||
func WithdrawCryptocurrencyFundsByExchange(exchName string, req *exchange.CryptoWithdrawRequest) (string, error) {
|
||||
if req == nil {
|
||||
return "", errors.New("crypto withdraw request param is nil")
|
||||
}
|
||||
|
||||
exch := GetExchangeByName(exchName)
|
||||
if exch == nil {
|
||||
return "", ErrExchangeNotFound
|
||||
}
|
||||
|
||||
// TO-DO: FILL
|
||||
return exch.WithdrawCryptocurrencyFunds(&exchange.CryptoWithdrawRequest{})
|
||||
return exch.WithdrawCryptocurrencyFunds(req)
|
||||
}
|
||||
|
||||
// FormatCurrency is a method that formats and returns a currency pair
|
||||
|
||||
@@ -64,8 +64,6 @@ func (o *orderManager) Start() error {
|
||||
|
||||
log.Debugln("Order manager starting...")
|
||||
|
||||
// test param
|
||||
o.cfg.CancelOrdersOnShutdown = true
|
||||
o.shutdown = make(chan struct{})
|
||||
o.orderStore.Orders = make(map[string][]exchange.OrderDetail)
|
||||
go o.run()
|
||||
|
||||
@@ -727,7 +727,8 @@ func (s *RPCServer) GetCryptocurrencyDepositAddresses(ctx context.Context, r *gc
|
||||
return nil, errors.New("exchange is not loaded/doesn't exist")
|
||||
}
|
||||
|
||||
return &gctrpc.GetCryptocurrencyDepositAddressesResponse{}, common.ErrNotYetImplemented
|
||||
result, err := GetCryptocurrencyDepositAddressesByExchange(r.Exchange)
|
||||
return &gctrpc.GetCryptocurrencyDepositAddressesResponse{Addresses: result}, err
|
||||
}
|
||||
|
||||
// GetCryptocurrencyDepositAddress returns a cryptocurrency deposit address
|
||||
@@ -738,7 +739,7 @@ func (s *RPCServer) GetCryptocurrencyDepositAddress(ctx context.Context, r *gctr
|
||||
return nil, errors.New("exchange is not loaded/doesn't exist")
|
||||
}
|
||||
|
||||
addr, err := exch.GetDepositAddress(currency.NewCode(r.Cryptocurrency), "")
|
||||
addr, err := GetExchangeCryptocurrencyDepositAddress(r.Exchange, "", currency.NewCode(r.Cryptocurrency))
|
||||
return &gctrpc.GetCryptocurrencyDepositAddressResponse{Address: addr}, err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user