mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
gctrpc: endpoints now optionally return timestamps in nanoseconds (configurable) (#718)
* config: add remoteControl/gRPC/timeInNanoSeconds * grpc: consult with remoteControl/gRPC/timeInNanoSeconds whether timestamps should be in seconds or nanos * engine: test if RPCServer.unixTimestamp() respects config/remoteControl/gRPC/timeInNanoSeconds * engine: implement TestRPCServer_GetTicker_LastUpdatedNanos that makes sure TickerResponse.LastUpdated is returned in nanoseconds if configured * config_example.json: add remoteControl/gRPC/timeInNanoSeconds * engine: (1) test RPCServer.unixTimestamp() in parallel, (2) increase time tolerance of TestRPCServer_GetTicker_LastUpdatedNanos() * engine: TestRPCServer_GetTicker_LastUpdatedNanos() now fetches a mock-up ticker to check timestamps
This commit is contained in:
@@ -179,6 +179,7 @@ type GRPCConfig struct {
|
||||
ListenAddress string `json:"listenAddress"`
|
||||
GRPCProxyEnabled bool `json:"grpcProxyEnabled"`
|
||||
GRPCProxyListenAddress string `json:"grpcProxyListenAddress"`
|
||||
TimeInNanoSeconds bool `json:"timeInNanoSeconds"`
|
||||
}
|
||||
|
||||
// DepcrecatedRPCConfig stores the deprecatedRPCConfig settings
|
||||
|
||||
@@ -183,7 +183,8 @@
|
||||
"enabled": true,
|
||||
"listenAddress": "localhost:9052",
|
||||
"grpcProxyEnabled": false,
|
||||
"grpcProxyListenAddress": "localhost:9053"
|
||||
"grpcProxyListenAddress": "localhost:9053",
|
||||
"timeInNanoSeconds": false
|
||||
},
|
||||
"deprecatedRPC": {
|
||||
"enabled": true,
|
||||
@@ -2451,4 +2452,4 @@
|
||||
"supportedExchanges": "Kraken,Bitstamp"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ func (s *RPCServer) GetTicker(_ context.Context, r *gctrpc.GetTickerRequest) (*g
|
||||
|
||||
resp := &gctrpc.TickerResponse{
|
||||
Pair: r.Pair,
|
||||
LastUpdated: t.LastUpdated.Unix(),
|
||||
LastUpdated: s.unixTimestamp(t.LastUpdated),
|
||||
Last: t.Last,
|
||||
High: t.High,
|
||||
Low: t.Low,
|
||||
@@ -394,7 +394,7 @@ func (s *RPCServer) GetTickers(_ context.Context, _ *gctrpc.GetTickersRequest) (
|
||||
Base: val.Pair.Base.String(),
|
||||
Quote: val.Pair.Quote.String(),
|
||||
},
|
||||
LastUpdated: val.LastUpdated.Unix(),
|
||||
LastUpdated: s.unixTimestamp(val.LastUpdated),
|
||||
Last: val.Last,
|
||||
High: val.High,
|
||||
Low: val.Low,
|
||||
@@ -456,7 +456,7 @@ func (s *RPCServer) GetOrderbook(_ context.Context, r *gctrpc.GetOrderbookReques
|
||||
Pair: r.Pair,
|
||||
Bids: bids,
|
||||
Asks: asks,
|
||||
LastUpdated: ob.LastUpdated.Unix(),
|
||||
LastUpdated: s.unixTimestamp(ob.LastUpdated),
|
||||
AssetType: r.AssetType,
|
||||
}
|
||||
|
||||
@@ -500,7 +500,7 @@ func (s *RPCServer) GetOrderbooks(_ context.Context, _ *gctrpc.GetOrderbooksRequ
|
||||
Quote: currencies[z].Quote.String(),
|
||||
},
|
||||
AssetType: assets[y].String(),
|
||||
LastUpdated: resp.LastUpdated.Unix(),
|
||||
LastUpdated: s.unixTimestamp(resp.LastUpdated),
|
||||
}
|
||||
for i := range resp.Bids {
|
||||
ob.Bids = append(ob.Bids, &gctrpc.OrderbookItem{
|
||||
@@ -911,7 +911,7 @@ func (s *RPCServer) GetOrders(_ context.Context, r *gctrpc.GetOrdersRequest) (*g
|
||||
Total: resp[x].Trades[i].Total,
|
||||
}
|
||||
if !resp[x].Trades[i].Timestamp.IsZero() {
|
||||
t.CreationTime = resp[x].Trades[i].Timestamp.Unix()
|
||||
t.CreationTime = s.unixTimestamp(resp[x].Trades[i].Timestamp)
|
||||
}
|
||||
trades = append(trades, t)
|
||||
}
|
||||
@@ -933,10 +933,10 @@ func (s *RPCServer) GetOrders(_ context.Context, r *gctrpc.GetOrdersRequest) (*g
|
||||
Trades: trades,
|
||||
}
|
||||
if !resp[x].Date.IsZero() {
|
||||
o.CreationTime = resp[x].Date.Unix()
|
||||
o.CreationTime = s.unixTimestamp(resp[x].Date)
|
||||
}
|
||||
if !resp[x].LastUpdated.IsZero() {
|
||||
o.UpdateTime = resp[x].LastUpdated.Unix()
|
||||
o.UpdateTime = s.unixTimestamp(resp[x].LastUpdated)
|
||||
}
|
||||
orders = append(orders, o)
|
||||
}
|
||||
@@ -995,7 +995,7 @@ func (s *RPCServer) GetManagedOrders(_ context.Context, r *gctrpc.GetOrdersReque
|
||||
Total: resp[x].Trades[i].Total,
|
||||
}
|
||||
if !resp[x].Trades[i].Timestamp.IsZero() {
|
||||
t.CreationTime = resp[x].Trades[i].Timestamp.Unix()
|
||||
t.CreationTime = s.unixTimestamp(resp[x].Trades[i].Timestamp)
|
||||
}
|
||||
trades = append(trades, t)
|
||||
}
|
||||
@@ -1017,10 +1017,10 @@ func (s *RPCServer) GetManagedOrders(_ context.Context, r *gctrpc.GetOrdersReque
|
||||
Trades: trades,
|
||||
}
|
||||
if !resp[x].Date.IsZero() {
|
||||
o.CreationTime = resp[x].Date.Unix()
|
||||
o.CreationTime = s.unixTimestamp(resp[x].Date)
|
||||
}
|
||||
if !resp[x].LastUpdated.IsZero() {
|
||||
o.UpdateTime = resp[x].LastUpdated.Unix()
|
||||
o.UpdateTime = s.unixTimestamp(resp[x].LastUpdated)
|
||||
}
|
||||
orders = append(orders, o)
|
||||
}
|
||||
@@ -1062,7 +1062,7 @@ func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gct
|
||||
var trades []*gctrpc.TradeHistory
|
||||
for i := range result.Trades {
|
||||
trades = append(trades, &gctrpc.TradeHistory{
|
||||
CreationTime: result.Trades[i].Timestamp.Unix(),
|
||||
CreationTime: s.unixTimestamp(result.Trades[i].Timestamp),
|
||||
Id: result.Trades[i].TID,
|
||||
Price: result.Trades[i].Price,
|
||||
Amount: result.Trades[i].Amount,
|
||||
@@ -1075,11 +1075,11 @@ func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gct
|
||||
}
|
||||
|
||||
var creationTime, updateTime int64
|
||||
if result.Date.Unix() > 0 {
|
||||
creationTime = result.Date.Unix()
|
||||
if !result.Date.IsZero() {
|
||||
creationTime = s.unixTimestamp(result.Date)
|
||||
}
|
||||
if result.LastUpdated.Unix() > 0 {
|
||||
updateTime = result.LastUpdated.Unix()
|
||||
if !result.LastUpdated.IsZero() {
|
||||
updateTime = s.unixTimestamp(result.LastUpdated)
|
||||
}
|
||||
|
||||
return &gctrpc.OrderDetails{
|
||||
@@ -1924,7 +1924,7 @@ func (s *RPCServer) GetTickerStream(r *gctrpc.GetTickerStreamRequest, stream gct
|
||||
Base: t.Pair.Base.String(),
|
||||
Quote: t.Pair.Quote.String(),
|
||||
Delimiter: t.Pair.Delimiter},
|
||||
LastUpdated: t.LastUpdated.Unix(),
|
||||
LastUpdated: s.unixTimestamp(t.LastUpdated),
|
||||
Last: t.Last,
|
||||
High: t.High,
|
||||
Low: t.Low,
|
||||
@@ -1969,7 +1969,7 @@ func (s *RPCServer) GetExchangeTickerStream(r *gctrpc.GetExchangeTickerStreamReq
|
||||
Base: t.Pair.Base.String(),
|
||||
Quote: t.Pair.Quote.String(),
|
||||
Delimiter: t.Pair.Delimiter},
|
||||
LastUpdated: t.LastUpdated.Unix(),
|
||||
LastUpdated: s.unixTimestamp(t.LastUpdated),
|
||||
Last: t.Last,
|
||||
High: t.High,
|
||||
Low: t.Low,
|
||||
@@ -3656,3 +3656,12 @@ func (s *RPCServer) GetDataHistoryJobSummary(_ context.Context, r *gctrpc.GetDat
|
||||
ResultSummaries: job.ResultRanges,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// unixTimestamp returns given time in either unix seconds or unix nanoseconds, depending
|
||||
// on the remoteControl/gRPC/timeInNanoSeconds boolean configuration.
|
||||
func (s *RPCServer) unixTimestamp(x time.Time) int64 {
|
||||
if s.Config.RemoteControl.GRPC.TimeInNanoSeconds {
|
||||
return x.UnixNano()
|
||||
}
|
||||
return x.Unix()
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/binance"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/trade"
|
||||
"github.com/thrasher-corp/gocryptotrader/gctrpc"
|
||||
"github.com/thrasher-corp/gocryptotrader/portfolio/banking"
|
||||
@@ -1688,3 +1689,96 @@ func TestGetManagedOrders(t *testing.T) {
|
||||
t.Errorf("unexpected order result: %v", oo)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRPCServer_unixTimestamp(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := RPCServer{
|
||||
Engine: &Engine{
|
||||
Config: &config.Config{
|
||||
RemoteControl: config.RemoteControlConfig{
|
||||
GRPC: config.GRPCConfig{
|
||||
TimeInNanoSeconds: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
const sec = 1618888141
|
||||
const nsec = 2
|
||||
x := time.Unix(sec, nsec)
|
||||
|
||||
timestampSeconds := s.unixTimestamp(x)
|
||||
if timestampSeconds != sec {
|
||||
t.Errorf("have %d, want %d", timestampSeconds, sec)
|
||||
}
|
||||
|
||||
s.Config.RemoteControl.GRPC.TimeInNanoSeconds = true
|
||||
timestampNanos := s.unixTimestamp(x)
|
||||
if want := int64(sec*1_000_000_000 + nsec); timestampNanos != want {
|
||||
t.Errorf("have %d, want %d", timestampSeconds, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRPCServer_GetTicker_LastUpdatedNanos(t *testing.T) {
|
||||
// Make a dummy pair we'll be using for this test.
|
||||
pair := currency.NewPairWithDelimiter("XXXXX", "YYYYY", "")
|
||||
|
||||
// Create a mock-up RPCServer and add our newly made pair to its list of available
|
||||
// and enabled pairs.
|
||||
server := RPCServer{Engine: RPCTestSetup(t)}
|
||||
b := server.ExchangeManager.GetExchangeByName(testExchange).GetBase()
|
||||
b.CurrencyPairs.Pairs[asset.Spot].Available = append(
|
||||
b.CurrencyPairs.Pairs[asset.Spot].Available,
|
||||
pair,
|
||||
)
|
||||
b.CurrencyPairs.Pairs[asset.Spot].Enabled = append(
|
||||
b.CurrencyPairs.Pairs[asset.Spot].Enabled,
|
||||
pair,
|
||||
)
|
||||
|
||||
// Push a mock-up ticker.
|
||||
now := time.Now()
|
||||
ticker.ProcessTicker(&ticker.Price{
|
||||
ExchangeName: testExchange,
|
||||
Pair: pair,
|
||||
AssetType: asset.Spot,
|
||||
LastUpdated: now,
|
||||
|
||||
Open: 69,
|
||||
High: 96,
|
||||
Low: 169,
|
||||
Close: 196,
|
||||
})
|
||||
|
||||
// Prepare a ticker request.
|
||||
request := &gctrpc.GetTickerRequest{
|
||||
Exchange: testExchange,
|
||||
Pair: &gctrpc.CurrencyPair{
|
||||
Delimiter: pair.Delimiter,
|
||||
Base: pair.Base.String(),
|
||||
Quote: pair.Quote.String(),
|
||||
},
|
||||
AssetType: asset.Spot.String(),
|
||||
}
|
||||
|
||||
// Check if timestamp returned is in seconds if !TimeInNanoSeconds.
|
||||
server.Config.RemoteControl.GRPC.TimeInNanoSeconds = false
|
||||
one, err := server.GetTicker(context.Background(), request)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if want := now.Unix(); one.LastUpdated != want {
|
||||
t.Errorf("have %d, want %d", one.LastUpdated, want)
|
||||
}
|
||||
|
||||
// Check if timestamp returned is in nanoseconds if TimeInNanoSeconds.
|
||||
server.Config.RemoteControl.GRPC.TimeInNanoSeconds = true
|
||||
two, err := server.GetTicker(context.Background(), request)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if want := now.UnixNano(); two.LastUpdated != want {
|
||||
t.Errorf("have %d, want %d", two.LastUpdated, want)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user