Skip to content

Commit

Permalink
add sync server time service (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sagleft authored Jul 10, 2023
1 parent 9bf07d3 commit e03fd39
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 4 deletions.
33 changes: 29 additions & 4 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ type Client struct {
key string
secret string

checkResponseBody checkResponseBodyFunc
checkResponseBody checkResponseBodyFunc
syncTimeDeltaNanoSeconds int64
}

// NewClient :
Expand Down Expand Up @@ -399,7 +400,31 @@ func (c *Client) deletePrivately(path string, query url.Values, dst interface{})
}

func (c *Client) getTimestamp() int64 {
now := time.Now()
unixNano := now.UnixNano()
return unixNano / 1000000
return (time.Now().UnixNano() - c.syncTimeDeltaNanoSeconds) / 1000000
}

func (c *Client) updateSyncTimeDelta(
remoteServerTimeRaw string,
localTimestampNanoseconds int64,
) error {
remoteServerTimeNS, err := strconv.ParseInt(remoteServerTimeRaw, 10, 64)
if err != nil {
return fmt.Errorf("parse server time: %w", err)
}

c.syncTimeDeltaNanoSeconds = localTimestampNanoseconds - remoteServerTimeNS
return nil
}

func (c *Client) SyncServerTime() error {
r, err := c.NewTimeService().GetServerTime()
if err != nil {
return fmt.Errorf("get server time: %w", err)
}

if r.RetMsg != "OK" {
return fmt.Errorf("get server time: %s", r.RetMsg)
}

return c.updateSyncTimeDelta(r.Result.TimeNano, time.Now().UnixNano())
}
5 changes: 5 additions & 0 deletions client_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ func (c *Client) Spot() SpotServiceI {
return &SpotService{c}
}

// NewTimeService :
func (c *Client) NewTimeService() TimeServiceI {
return &TimeService{c}
}

// FutureServiceI :
type FutureServiceI interface {
InversePerpetual() FutureInversePerpetualServiceI
Expand Down
33 changes: 33 additions & 0 deletions time_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package bybit

// TimeService :
type TimeService struct {
client *Client
}

// TimeServiceI :
type TimeServiceI interface {
GetServerTime() (*GetServerTimeResponse, error)
}

// GetServerTimeResponse :
type GetServerTimeResponse struct {
CommonResponse `json:",inline"`
Result GetServerTimeResult `json:"result"`
}

type GetServerTimeResult struct {
TimeSecond string `json:"timeSecond"`
TimeNano string `json:"timeNano"`
}

// GetServerTime :
func (s *TimeService) GetServerTime() (*GetServerTimeResponse, error) {
var res GetServerTimeResponse

if err := s.client.getPublicly("/v3/public/time", nil, &res); err != nil {
return nil, err
}

return &res, nil
}
30 changes: 30 additions & 0 deletions time_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package bybit

import (
"math"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestUpdateSyncTimeDelta(t *testing.T) {
// given
c := &Client{}
remoteServerTimeRaw := "1688721231460000000"
localTimestampNanoseconds := int64(1688721231560000000)
expectedNsDelta := int64(100000000)
recvWindowMs := int64(5000)
nowTimestampMs := time.Now().UnixMilli()

// when
err := c.updateSyncTimeDelta(remoteServerTimeRaw, localTimestampNanoseconds)

// then
require.NoError(t, err)
assert.Equal(t, expectedNsDelta, c.syncTimeDeltaNanoSeconds)

timestampMsDelta := int64(math.Abs(float64(c.getTimestamp()) - float64(nowTimestampMs)))
assert.Less(t, timestampMsDelta, recvWindowMs)
}

0 comments on commit e03fd39

Please sign in to comment.