exchanges/GateIO, OKX: Fix and optimise websocket request ID message generation (#2103)

* gatio: fix MessageID regression (cherry-pick me)

* Update exchanges/gateio/gateio_wrapper_test.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* glorious: AI

* Update exchanges/gateio/gateio_wrapper.go

Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com>

* thrasher: use optimisation in okx as well

* okx: Add length check in tests for string -> uuid conversion

* thrasher: nits

---------

Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com>
This commit is contained in:
Ryan O'Hara-Reid
2025-11-11 14:25:21 +11:00
committed by GitHub
parent 2fd4f5ec5b
commit fefb866b02
6 changed files with 60 additions and 20 deletions

View File

@@ -2940,5 +2940,5 @@ func TestMessageID(t *testing.T) {
require.NotEmpty(t, id, "MessageID must return a non-empty message ID")
u, err := uuid.FromString(id)
require.NoError(t, err, "MessageID must return a valid UUID")
assert.Equal(t, byte(0x7), u.Version(), "MessageID should return a V7 uuid")
assert.Equal(t, uuid.V7, u.Version(), "MessageID should return a V7 uuid")
}

View File

@@ -2,6 +2,7 @@ package gateio
import (
"context"
"encoding/hex"
"errors"
"fmt"
"math"
@@ -11,6 +12,7 @@ import (
"strings"
"time"
"github.com/gofrs/uuid"
"github.com/shopspring/decimal"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/common/key"
@@ -2645,3 +2647,11 @@ func (e *Exchange) WebsocketSubmitOrders(ctx context.Context, orders []*order.Su
return nil, fmt.Errorf("%w for %s", common.ErrNotYetImplemented, a)
}
}
// MessageID returns a unique ID conforming to Gate's max length of 32 bytes for request IDs
func (e *Exchange) MessageID() string {
u := uuid.Must(uuid.NewV7())
var buf [32]byte
hex.Encode(buf[:], u[:])
return string(buf[:])
}

View File

@@ -3,6 +3,7 @@ package gateio
import (
"testing"
"github.com/gofrs/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/thrasher-corp/gocryptotrader/currency"
@@ -71,3 +72,20 @@ func TestCancelAllOrders(t *testing.T) {
})
}
}
func TestMessageID(t *testing.T) {
t.Parallel()
id := e.MessageID()
require.Len(t, id, 32, "message ID must be 32 characters long for usage as a request ID")
got, err := uuid.FromString(id)
require.NoError(t, err, "ID string must convert back to a UUID")
require.Equal(t, uuid.V7, got.Version(), "message ID must be a UUID v7")
require.Len(t, got.String(), 36, "UUID v7 string representation must be 36 characters long")
}
// 7610378 143.3 ns/op 48 B/op 2 allocs/op
func BenchmarkMessageID(b *testing.B) {
for b.Loop() {
_ = e.MessageID()
}
}

View File

@@ -2,6 +2,7 @@ package okx
import (
"context"
"encoding/hex"
"errors"
"fmt"
"math"
@@ -3022,5 +3023,8 @@ func (e *Exchange) GetCurrencyTradeURL(ctx context.Context, a asset.Item, cp cur
// MessageID returns a universally unique ID using UUID V7, with hyphens removed to fit the maximum 32-character field for okx
func (e *Exchange) MessageID() string {
return strings.Replace(uuid.Must(uuid.NewV7()).String(), "-", "", 4)
u := uuid.Must(uuid.NewV7())
var buf [32]byte
hex.Encode(buf[:], u[:])
return string(buf[:])
}

View File

@@ -0,0 +1,26 @@
package okx
import (
"testing"
"github.com/gofrs/uuid"
"github.com/stretchr/testify/require"
)
func TestMessageID(t *testing.T) {
t.Parallel()
id := new(Exchange).MessageID()
require.Len(t, id, 32, "Must return the correct length of message id")
u, err := uuid.FromString(id)
require.NoError(t, err, "MessageID must return a valid UUID")
require.Equal(t, uuid.V7, u.Version(), "MessageID must return a V7 uuid")
require.Len(t, u.String(), 36, "UUID v7 string representation must be 36 characters long")
}
// 7696807 153.1 ns/op 48 B/op 2 allocs/op
func BenchmarkMessageID(b *testing.B) {
e := new(Exchange)
for b.Loop() {
_ = e.MessageID()
}
}

View File

@@ -4,7 +4,6 @@ import (
"errors"
"testing"
"github.com/gofrs/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/thrasher-corp/gocryptotrader/common"
@@ -282,20 +281,3 @@ func TestSingleItem(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, got)
}
func TestMessageID(t *testing.T) {
t.Parallel()
id := new(Exchange).MessageID()
require.Len(t, id, 32, "Must return the correct length of message id")
u, err := uuid.FromString(id)
require.NoError(t, err, "MessageID must return a valid UUID")
assert.Equal(t, byte(0x7), u.Version(), "MessageID should return a V7 uuid")
}
// BenchmarkMessageID-8 4736883 259.9 ns/op 96 B/op 4 allocs/op
func BenchmarkMessageID(b *testing.B) {
e := new(Exchange)
for b.Loop() {
_ = e.MessageID()
}
}