Merge branch 'master' into engine

This commit is contained in:
Adrian Gallagher
2019-06-21 18:10:55 +10:00
87 changed files with 5669 additions and 992 deletions

View File

@@ -1,12 +1,17 @@
package gateio
import (
"net/http"
"strings"
"testing"
"time"
"github.com/gorilla/websocket"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/sharedtestvalues"
)
// Please supply your own APIKEYS here for due diligence testing
@@ -31,6 +36,7 @@ func TestSetup(t *testing.T) {
t.Error("Test Failed - GateIO Setup() init error")
}
gateioConfig.API.AuthenticatedSupport = true
gateioConfig.API.AuthenticatedWebsocketSupport = true
gateioConfig.API.Credentials.Key = apiKey
gateioConfig.API.Credentials.Secret = apiSecret
@@ -493,3 +499,48 @@ func TestGetOrderInfo(t *testing.T) {
}
}
}
// TestWsAuth dials websocket, sends login request.
func TestWsAuth(t *testing.T) {
g.SetDefaults()
TestSetup(t)
if !g.Websocket.IsEnabled() && !g.API.AuthenticatedWebsocketSupport || !areTestAPIKeysSet() {
t.Skip(exchange.WebsocketNotEnabled)
}
var err error
var dialer websocket.Dialer
g.WebsocketConn, _, err = dialer.Dial(g.Websocket.GetWebsocketURL(),
http.Header{})
if err != nil {
t.Fatal(err)
}
g.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride()
g.Websocket.TrafficAlert = sharedtestvalues.GetWebsocketStructChannelOverride()
go g.WsHandleData()
defer g.WebsocketConn.Close()
err = g.wsServerSignIn()
if err != nil {
t.Error(err)
}
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case resultString := <-g.Websocket.DataHandler:
if !strings.Contains(resultString.(string), "success") {
t.Error("Authentication failed")
}
case <-timer.C:
t.Error("Expected response")
}
timer.Stop()
err = g.wsGetBalance()
if err != nil {
t.Error(err)
}
timer = time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
select {
case <-g.Websocket.DataHandler:
case <-timer.C:
t.Error("Expected response")
}
timer.Stop()
}

View File

@@ -48,22 +48,21 @@ func (g *Gateio) WsConnect() error {
if err != nil {
return err
}
if g.API.AuthenticatedSupport {
err = g.wsServerSignIn()
if err != nil {
log.Errorf("%v - wsServerSignin() failed: %v", g.GetName(), err)
}
time.Sleep(time.Second * 2) // sleep to allow server to complete sign-on if further authenticated requests are sent piror to this they will fail
}
go g.WsHandleData()
g.GenerateDefaultSubscriptions()
err = g.wsServerSignIn()
if err != nil {
log.Errorf("%v - authentication failed: %v", g.Name, err)
}
g.GenerateAuthenticatedSubscriptions()
g.GenerateDefaultSubscriptions()
return nil
}
func (g *Gateio) wsServerSignIn() error {
if !g.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", g.Name)
}
nonce := int(time.Now().Unix() * 1000)
sigTemp := g.GenerateSignature(strconv.Itoa(nonce))
signature := crypto.Base64Encode(sigTemp)
@@ -72,7 +71,13 @@ func (g *Gateio) wsServerSignIn() error {
Method: "server.sign",
Params: []interface{}{g.API.Credentials.Key, signature, nonce},
}
return g.wsSend(signinWsRequest)
err := g.wsSend(signinWsRequest)
if err != nil {
g.Websocket.SetCanUseAuthenticatedEndpoints(false)
return err
}
time.Sleep(time.Second * 2) // sleep to allow server to complete sign-on if further authenticated requests are sent prior to this they will fail
return nil
}
// WsReadData reads from the websocket connection and returns the websocket
@@ -116,20 +121,22 @@ func (g *Gateio) WsHandleData() {
g.Websocket.DataHandler <- err
continue
}
if result.Error.Code != 0 {
if strings.Contains(result.Error.Message, "authentication") {
g.Websocket.DataHandler <- fmt.Errorf("%v - WebSocket authentication failed ",
g.GetName())
g.API.AuthenticatedSupport = false
g.Websocket.DataHandler <- fmt.Errorf("%v - authentication failed: %v", g.Name, err)
g.Websocket.SetCanUseAuthenticatedEndpoints(false)
continue
}
g.Websocket.DataHandler <- fmt.Errorf("gateio_websocket.go error %s",
result.Error.Message)
g.Websocket.DataHandler <- fmt.Errorf("%v error %s",
g.Name, result.Error.Message)
continue
}
switch result.ID {
case IDSignIn:
g.Websocket.SetCanUseAuthenticatedEndpoints(true)
g.Websocket.DataHandler <- string(result.Result)
case IDBalance:
var balance WebsocketBalance
var balanceInterface interface{}
@@ -342,14 +349,29 @@ func (g *Gateio) WsHandleData() {
}
}
// GenerateAuthenticatedSubscriptions Adds authenticated subscriptions to websocket to be handled by ManageSubscriptions()
func (g *Gateio) GenerateAuthenticatedSubscriptions() {
if !g.Websocket.CanUseAuthenticatedEndpoints() {
return
}
var channels = []string{"balance.subscribe", "order.subscribe"}
var subscriptions []exchange.WebsocketChannelSubscription
enabledCurrencies := g.GetEnabledPairs(asset.Spot)
for i := range channels {
for j := range enabledCurrencies {
subscriptions = append(subscriptions, exchange.WebsocketChannelSubscription{
Channel: channels[i],
Currency: enabledCurrencies[j],
})
}
}
g.Websocket.SubscribeToChannels(subscriptions)
}
// GenerateDefaultSubscriptions Adds default subscriptions to websocket to be handled by ManageSubscriptions()
func (g *Gateio) GenerateDefaultSubscriptions() {
var channels = []string{"ticker.subscribe", "trades.subscribe", "depth.subscribe", "kline.subscribe"}
if g.AllowAuthenticatedRequest() {
channels = append(channels, "balance.subscribe", "order.subscribe")
}
subscriptions := []exchange.WebsocketChannelSubscription{}
var subscriptions []exchange.WebsocketChannelSubscription
enabledCurrencies := g.GetEnabledPairs(asset.Spot)
for i := range channels {
for j := range enabledCurrencies {
@@ -402,6 +424,9 @@ func (g *Gateio) Unsubscribe(channelToSubscribe exchange.WebsocketChannelSubscri
}
func (g *Gateio) wsGetBalance() error {
if !g.Websocket.CanUseAuthenticatedEndpoints() {
return fmt.Errorf("%v not authorised to get balance", g.Name)
}
balanceWsRequest := WebsocketRequest{
ID: IDBalance,
Method: "balance.query",
@@ -411,6 +436,9 @@ func (g *Gateio) wsGetBalance() error {
}
func (g *Gateio) wsGetOrderInfo(market string, offset, limit int) error {
if !g.Websocket.CanUseAuthenticatedEndpoints() {
return fmt.Errorf("%v not authorised to get order info", g.Name)
}
order := WebsocketRequest{
ID: IDOrderQuery,
Method: "order.query",

View File

@@ -575,3 +575,13 @@ func (g *Gateio) UnsubscribeToWebsocketChannels(channels []exchange.WebsocketCha
g.Websocket.UnsubscribeToChannels(channels)
return nil
}
// GetSubscriptions returns a copied list of subscriptions
func (g *Gateio) GetSubscriptions() ([]exchange.WebsocketChannelSubscription, error) {
return g.Websocket.GetSubscriptions(), nil
}
// AuthenticateWebsocket sends an authentication message to the websocket
func (g *Gateio) AuthenticateWebsocket() error {
return g.wsServerSignIn()
}