Fix Coinut nonce issue based on new API nonce rule (#456)

This commit is contained in:
Adrian Gallagher
2020-02-28 16:31:52 +11:00
committed by GitHub
parent ade3220673
commit 31fe74a380
4 changed files with 30 additions and 26 deletions

View File

@@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"net/http"
"strconv"
"strings"
@@ -40,6 +41,7 @@ const (
coinutPositionOpen = "user_open_positions"
coinutStatusOK = "OK"
coinutMaxNonce = 16777215 // See https://github.com/coinut/api/wiki/Websocket-API#nonce
)
var (
@@ -269,12 +271,11 @@ func (c *COINUT) SendHTTPRequest(apiRequest string, params map[string]interface{
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, c.Name)
}
n := c.Requester.GetNonce(false)
if params == nil {
params = map[string]interface{}{}
}
params["nonce"] = n
params["nonce"] = getNonce()
params["request"] = apiRequest
payload, err := json.Marshal(params)
@@ -302,7 +303,6 @@ func (c *COINUT) SendHTTPRequest(apiRequest string, params map[string]interface{
Body: bytes.NewBuffer(payload),
Result: &rawMsg,
AuthRequest: authenticated,
NonceEnabled: true,
Verbose: c.Verbose,
HTTPDebugging: c.HTTPDebugging,
HTTPRecording: c.HTTPRecording,
@@ -495,3 +495,7 @@ func (i *instrumentMap) GetInstrumentIDs() []int64 {
}
return instruments
}
func getNonce() int64 {
return rand.Int63n(coinutMaxNonce-1) + 1
}

View File

@@ -640,3 +640,12 @@ func TestCurrencyMapInstrumentIDs(t *testing.T) {
t.Error("unexpected result")
}
}
func TestGetNonce(t *testing.T) {
result := getNonce()
for x := 0; x < 100000; x++ {
if result <= 0 || result > coinutMaxNonce {
t.Fatal("invalid nonce value")
}
}
}

View File

@@ -233,24 +233,13 @@ func (c *COINUT) wsProcessResponse(resp []byte) {
}
}
// GetNonce returns a nonce for a required request
func (c *COINUT) GetNonce() int64 {
if c.Nonce.Get() == 0 {
c.Nonce.Set(time.Now().Unix())
} else {
c.Nonce.Inc()
}
return int64(c.Nonce.Get())
}
// WsGetInstruments fetches instrument list and propagates a local cache
func (c *COINUT) WsGetInstruments() (Instruments, error) {
var list Instruments
request := wsRequest{
Request: "inst_list",
SecType: strings.ToUpper(asset.Spot.String()),
Nonce: c.WebsocketConn.GenerateMessageID(false),
Nonce: getNonce(),
}
resp, err := c.WebsocketConn.SendMessageReturnResponse(request.Nonce, request)
if err != nil {
@@ -344,7 +333,7 @@ func (c *COINUT) Subscribe(channelToSubscribe wshandler.WebsocketChannelSubscrip
InstID: c.instrumentMap.LookupID(c.FormatExchangeCurrency(channelToSubscribe.Currency,
asset.Spot).String()),
Subscribe: true,
Nonce: c.WebsocketConn.GenerateMessageID(false),
Nonce: getNonce(),
}
return c.WebsocketConn.SendJSONMessage(subscribe)
}
@@ -356,7 +345,7 @@ func (c *COINUT) Unsubscribe(channelToSubscribe wshandler.WebsocketChannelSubscr
InstID: c.instrumentMap.LookupID(c.FormatExchangeCurrency(channelToSubscribe.Currency,
asset.Spot).String()),
Subscribe: false,
Nonce: c.WebsocketConn.GenerateMessageID(false),
Nonce: getNonce(),
}
resp, err := c.WebsocketConn.SendMessageReturnResponse(subscribe.Nonce, subscribe)
if err != nil {
@@ -378,7 +367,7 @@ func (c *COINUT) wsAuthenticate() error {
return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", c.Name)
}
timestamp := time.Now().Unix()
nonce := c.WebsocketConn.GenerateMessageID(false)
nonce := getNonce()
payload := c.API.Credentials.ClientID + "|" +
strconv.FormatInt(timestamp, 10) + "|" +
strconv.FormatInt(nonce, 10)
@@ -420,7 +409,7 @@ func (c *COINUT) wsGetAccountBalance() (*UserBalance, error) {
}
accBalance := wsRequest{
Request: "user_balance",
Nonce: c.WebsocketConn.GenerateMessageID(false),
Nonce: getNonce(),
}
resp, err := c.WebsocketConn.SendMessageReturnResponse(accBalance.Nonce, accBalance)
if err != nil {
@@ -444,7 +433,7 @@ func (c *COINUT) wsSubmitOrder(o *WsSubmitOrderParameters) (*WsStandardOrderResp
curr := c.FormatExchangeCurrency(o.Currency, asset.Spot).String()
var orderSubmissionRequest WsSubmitOrderRequest
orderSubmissionRequest.Request = "new_order"
orderSubmissionRequest.Nonce = c.WebsocketConn.GenerateMessageID(false)
orderSubmissionRequest.Nonce = getNonce()
orderSubmissionRequest.InstID = c.instrumentMap.LookupID(curr)
orderSubmissionRequest.Qty = o.Amount
orderSubmissionRequest.Price = o.Price
@@ -561,7 +550,7 @@ func (c *COINUT) wsSubmitOrders(orders []WsSubmitOrderParameters) ([]WsStandardO
})
}
orderRequest.Nonce = c.WebsocketConn.GenerateMessageID(false)
orderRequest.Nonce = getNonce()
orderRequest.Request = "new_orders"
resp, err := c.WebsocketConn.SendMessageReturnResponse(orderRequest.Nonce, orderRequest)
if err != nil {
@@ -612,7 +601,7 @@ func (c *COINUT) wsGetOpenOrders(curr string) (*WsUserOpenOrdersResponse, error)
}
var openOrdersRequest WsGetOpenOrdersRequest
openOrdersRequest.Request = "user_open_orders"
openOrdersRequest.Nonce = c.WebsocketConn.GenerateMessageID(false)
openOrdersRequest.Nonce = getNonce()
openOrdersRequest.InstID = c.instrumentMap.LookupID(curr)
resp, err := c.WebsocketConn.SendMessageReturnResponse(openOrdersRequest.Nonce, openOrdersRequest)
@@ -641,7 +630,7 @@ func (c *COINUT) wsCancelOrder(cancellation *WsCancelOrderParameters) (*CancelOr
cancellationRequest.Request = "cancel_order"
cancellationRequest.InstID = c.instrumentMap.LookupID(curr)
cancellationRequest.OrderID = cancellation.OrderID
cancellationRequest.Nonce = c.WebsocketConn.GenerateMessageID(false)
cancellationRequest.Nonce = getNonce()
resp, err := c.WebsocketConn.SendMessageReturnResponse(cancellationRequest.Nonce, cancellationRequest)
if err != nil {
@@ -677,7 +666,7 @@ func (c *COINUT) wsCancelOrders(cancellations []WsCancelOrderParameters) (*Cance
}
cancelOrderRequest.Request = "cancel_orders"
cancelOrderRequest.Nonce = c.WebsocketConn.GenerateMessageID(false)
cancelOrderRequest.Nonce = getNonce()
resp, err := c.WebsocketConn.SendMessageReturnResponse(cancelOrderRequest.Nonce, cancelOrderRequest)
if err != nil {
return response, err
@@ -698,7 +687,7 @@ func (c *COINUT) wsGetTradeHistory(p currency.Pair, start, limit int64) (*WsTrad
var request WsTradeHistoryRequest
request.Request = "trade_history"
request.InstID = c.instrumentMap.LookupID(curr)
request.Nonce = c.WebsocketConn.GenerateMessageID(false)
request.Nonce = getNonce()
request.Start = start
request.Limit = limit

View File

@@ -3,6 +3,7 @@ package coinut
import (
"errors"
"fmt"
"math/rand"
"strconv"
"strings"
"sync"
@@ -125,6 +126,7 @@ func (c *COINUT) SetDefaults() {
c.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit
c.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout
c.WebsocketOrderbookBufferLimit = exchange.DefaultWebsocketOrderbookBufferLimit
rand.Seed(time.Now().UnixNano())
}
// Setup sets the current exchange configuration