Skip to content

Commit 14b01e5

Browse files
SQS-377 | Unit test ProcessPool (#493)
* SQS-377 | Unit test ProcessPool Introduces unit tests for Orderbook usecase ProcessPool method.
1 parent 99e5abc commit 14b01e5

File tree

6 files changed

+371
-86
lines changed

6 files changed

+371
-86
lines changed

domain/mocks/orderbook_grpc_client_mock.go

+18
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ type OrderbookGRPCClientMock struct {
1515
MockGetOrdersByTickCb func(ctx context.Context, contractAddress string, tick int64) ([]orderbookplugindomain.Order, error)
1616
MockGetActiveOrdersCb func(ctx context.Context, contractAddress string, ownerAddress string) (orderbookdomain.Orders, uint64, error)
1717
MockGetTickUnrealizedCancelsCb func(ctx context.Context, contractAddress string, tickIDs []int64) ([]orderbookgrpcclientdomain.UnrealizedTickCancels, error)
18+
FetchTickUnrealizedCancelsCb func(ctx context.Context, chunkSize int, contractAddress string, tickIDs []int64) ([]orderbookgrpcclientdomain.UnrealizedTickCancels, error)
1819
MockQueryTicksCb func(ctx context.Context, contractAddress string, ticks []int64) ([]orderbookdomain.Tick, error)
20+
FetchTicksCb func(ctx context.Context, chunkSize int, contractAddress string, tickIDs []int64) ([]orderbookdomain.Tick, error)
1921
}
2022

2123
func (o *OrderbookGRPCClientMock) GetOrdersByTick(ctx context.Context, contractAddress string, tick int64) ([]orderbookplugindomain.Order, error) {
@@ -42,10 +44,26 @@ func (o *OrderbookGRPCClientMock) GetTickUnrealizedCancels(ctx context.Context,
4244
return nil, nil
4345
}
4446

47+
func (o *OrderbookGRPCClientMock) FetchTickUnrealizedCancels(ctx context.Context, chunkSize int, contractAddress string, tickIDs []int64) ([]orderbookgrpcclientdomain.UnrealizedTickCancels, error) {
48+
if o.FetchTickUnrealizedCancelsCb != nil {
49+
return o.FetchTickUnrealizedCancelsCb(ctx, chunkSize, contractAddress, tickIDs)
50+
}
51+
52+
return nil, nil
53+
}
54+
4555
func (o *OrderbookGRPCClientMock) QueryTicks(ctx context.Context, contractAddress string, ticks []int64) ([]orderbookdomain.Tick, error) {
4656
if o.MockQueryTicksCb != nil {
4757
return o.MockQueryTicksCb(ctx, contractAddress, ticks)
4858
}
4959

5060
return nil, nil
5161
}
62+
63+
func (o *OrderbookGRPCClientMock) FetchTicks(ctx context.Context, chunkSize int, contractAddress string, tickIDs []int64) ([]orderbookdomain.Tick, error) {
64+
if o.FetchTicksCb != nil {
65+
return o.FetchTicksCb(ctx, chunkSize, contractAddress, tickIDs)
66+
}
67+
68+
return nil, nil
69+
}

domain/orderbook/grpcclient/orderbook_grpc_client.go

+72-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package orderbookgrpcclientdomain
22

33
import (
44
"context"
5+
"fmt"
56

67
cosmwasmdomain "github.com/osmosis-labs/sqs/domain/cosmwasm"
78
orderbookdomain "github.com/osmosis-labs/sqs/domain/orderbook"
@@ -21,8 +22,22 @@ type OrderBookClient interface {
2122
// GetTickUnrealizedCancels fetches unrealized cancels by tick from the orderbook contract.
2223
GetTickUnrealizedCancels(ctx context.Context, contractAddress string, tickIDs []int64) ([]UnrealizedTickCancels, error)
2324

25+
// FetchTickUnrealizedCancels fetches the unrealized cancels for a given tick ID and contract address.
26+
// It returns the unrealized cancels and an error if any.
27+
// Errors if:
28+
// - failed to fetch unrealized cancels
29+
// - mismatch in number of unrealized cancels fetched
30+
FetchTickUnrealizedCancels(ctx context.Context, chunkSize int, contractAddress string, tickIDs []int64) ([]UnrealizedTickCancels, error)
31+
2432
// QueryTicks fetches ticks by tickIDs from the orderbook contract.
2533
QueryTicks(ctx context.Context, contractAddress string, ticks []int64) ([]orderbookdomain.Tick, error)
34+
35+
// FetchTicksForOrderbook fetches the ticks in chunks of maxQueryTicks at the time for a given tick ID and contract address.
36+
// It returns the ticks and an error if any.
37+
// Errors if:
38+
// - failed to fetch ticks
39+
// - mismatch in number of ticks fetched
40+
FetchTicks(ctx context.Context, chunkSize int, contractAddress string, tickIDs []int64) ([]orderbookdomain.Tick, error)
2641
}
2742

2843
// orderbookClientImpl is an implementation of OrderbookCWAPIClient.
@@ -39,7 +54,7 @@ func New(wasmClient wasmtypes.QueryClient) *orderbookClientImpl {
3954
}
4055
}
4156

42-
// GetOrdersByTick implements OrderbookCWAPIClient.
57+
// GetOrdersByTick implements OrderBookClient.
4358
func (o *orderbookClientImpl) GetOrdersByTick(ctx context.Context, contractAddress string, tick int64) ([]orderbookplugindomain.Order, error) {
4459
ordersByTick := ordersByTick{Tick: tick}
4560

@@ -51,7 +66,7 @@ func (o *orderbookClientImpl) GetOrdersByTick(ctx context.Context, contractAddre
5166
return orders.Orders, nil
5267
}
5368

54-
// GetActiveOrders implements OrderbookCWAPIClient.
69+
// GetActiveOrders implements OrderBookClient.
5570
func (o *orderbookClientImpl) GetActiveOrders(ctx context.Context, contractAddress string, ownerAddress string) (orderbookdomain.Orders, uint64, error) {
5671
var orders activeOrdersResponse
5772
if err := cosmwasmdomain.QueryCosmwasmContract(ctx, o.wasmClient, contractAddress, activeOrdersRequest{OrdersByOwner: ordersByOwner{Owner: ownerAddress}}, &orders); err != nil {
@@ -61,7 +76,7 @@ func (o *orderbookClientImpl) GetActiveOrders(ctx context.Context, contractAddre
6176
return orders.Orders, orders.Count, nil
6277
}
6378

64-
// GetTickUnrealizedCancels implements OrderbookCWAPIClient.
79+
// GetTickUnrealizedCancels implements OrderBookClient.
6580
func (o *orderbookClientImpl) GetTickUnrealizedCancels(ctx context.Context, contractAddress string, tickIDs []int64) ([]UnrealizedTickCancels, error) {
6681
var unrealizedCancels unrealizedCancelsResponse
6782
if err := cosmwasmdomain.QueryCosmwasmContract(ctx, o.wasmClient, contractAddress, unrealizedCancelsByTickIdRequest{UnrealizedCancels: unrealizedCancelsRequestPayload{TickIds: tickIDs}}, &unrealizedCancels); err != nil {
@@ -70,6 +85,33 @@ func (o *orderbookClientImpl) GetTickUnrealizedCancels(ctx context.Context, cont
7085
return unrealizedCancels.Ticks, nil
7186
}
7287

88+
// FetchTickUnrealizedCancels implements OrderBookClient.
89+
func (o *orderbookClientImpl) FetchTickUnrealizedCancels(ctx context.Context, chunkSize int, contractAddress string, tickIDs []int64) ([]UnrealizedTickCancels, error) {
90+
allUnrealizedCancels := make([]UnrealizedTickCancels, 0, len(tickIDs))
91+
92+
for i := 0; i < len(tickIDs); i += chunkSize {
93+
end := i + chunkSize
94+
if end > len(tickIDs) {
95+
end = len(tickIDs)
96+
}
97+
98+
currentTickIDs := tickIDs[i:end]
99+
100+
unrealizedCancels, err := o.GetTickUnrealizedCancels(ctx, contractAddress, currentTickIDs)
101+
if err != nil {
102+
return nil, fmt.Errorf("failed to fetch unrealized cancels for ticks %v: %w", currentTickIDs, err)
103+
}
104+
105+
allUnrealizedCancels = append(allUnrealizedCancels, unrealizedCancels...)
106+
}
107+
108+
if len(allUnrealizedCancels) != len(tickIDs) {
109+
return nil, fmt.Errorf("mismatch in number of unrealized cancels fetched: expected %d, got %d", len(tickIDs), len(allUnrealizedCancels))
110+
}
111+
112+
return allUnrealizedCancels, nil
113+
}
114+
73115
// QueryTicks implements OrderBookClient.
74116
func (o *orderbookClientImpl) QueryTicks(ctx context.Context, contractAddress string, ticks []int64) ([]orderbookdomain.Tick, error) {
75117
var orderbookTicks queryTicksResponse
@@ -78,3 +120,30 @@ func (o *orderbookClientImpl) QueryTicks(ctx context.Context, contractAddress st
78120
}
79121
return orderbookTicks.Ticks, nil
80122
}
123+
124+
// FetchTicks implements OrderBookClient.
125+
func (o *orderbookClientImpl) FetchTicks(ctx context.Context, chunkSize int, contractAddress string, tickIDs []int64) ([]orderbookdomain.Tick, error) {
126+
finalTickStates := make([]orderbookdomain.Tick, 0, len(tickIDs))
127+
128+
for i := 0; i < len(tickIDs); i += chunkSize {
129+
end := i + chunkSize
130+
if end > len(tickIDs) {
131+
end = len(tickIDs)
132+
}
133+
134+
currentTickIDs := tickIDs[i:end]
135+
136+
tickStates, err := o.QueryTicks(ctx, contractAddress, currentTickIDs)
137+
if err != nil {
138+
return nil, fmt.Errorf("failed to fetch ticks for pool %s: %w", contractAddress, err)
139+
}
140+
141+
finalTickStates = append(finalTickStates, tickStates...)
142+
}
143+
144+
if len(finalTickStates) != len(tickIDs) {
145+
return nil, fmt.Errorf("mismatch in number of ticks fetched: expected %d, got %d", len(tickIDs), len(finalTickStates))
146+
}
147+
148+
return finalTickStates, nil
149+
}

orderbook/types/errors.go

+60
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,63 @@ type ParsingPlacedAtError struct {
131131
func (e ParsingPlacedAtError) Error() string {
132132
return fmt.Sprintf("error parsing placed_at %s: %v", e.PlacedAt, e.Err)
133133
}
134+
135+
// PoolNilError represents an error when the pool is nil.
136+
type PoolNilError struct{}
137+
138+
func (e PoolNilError) Error() string {
139+
return "pool is nil when processing order book"
140+
}
141+
142+
// CosmWasmPoolModelNilError represents an error when the CosmWasmPoolModel is nil.
143+
type CosmWasmPoolModelNilError struct{}
144+
145+
func (e CosmWasmPoolModelNilError) Error() string {
146+
return "cw pool model is nil when processing order book"
147+
}
148+
149+
// NotAnOrderbookPoolError represents an error when the pool is not an orderbook pool.
150+
type NotAnOrderbookPoolError struct {
151+
PoolID uint64
152+
}
153+
154+
func (e NotAnOrderbookPoolError) Error() string {
155+
return fmt.Sprintf("pool is not an orderbook pool %d", e.PoolID)
156+
}
157+
158+
// FailedToCastPoolModelError represents an error when the pool model cannot be cast to a CosmWasmPool.
159+
type FailedToCastPoolModelError struct{}
160+
161+
func (e FailedToCastPoolModelError) Error() string {
162+
return "failed to cast pool model to CosmWasmPool"
163+
}
164+
165+
// FetchTicksError represents an error when fetching ticks fails.
166+
type FetchTicksError struct {
167+
ContractAddress string
168+
Err error
169+
}
170+
171+
func (e FetchTicksError) Error() string {
172+
return fmt.Sprintf("failed to fetch ticks for pool %s: %v", e.ContractAddress, e.Err)
173+
}
174+
175+
// FetchUnrealizedCancelsError represents an error when fetching unrealized cancels fails.
176+
type FetchUnrealizedCancelsError struct {
177+
ContractAddress string
178+
Err error
179+
}
180+
181+
func (e FetchUnrealizedCancelsError) Error() string {
182+
return fmt.Sprintf("failed to fetch unrealized cancels for pool %s: %v", e.ContractAddress, e.Err)
183+
}
184+
185+
// TickIDMismatchError represents an error when there is a mismatch between tick IDs.
186+
type TickIDMismatchError struct {
187+
ExpectedID int64
188+
ActualID int64
189+
}
190+
191+
func (e TickIDMismatchError) Error() string {
192+
return fmt.Sprintf("tick id mismatch when fetching tick states %d %d", e.ExpectedID, e.ActualID)
193+
}

orderbook/usecase/export_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
)
66

77
// OrderBookEntry is an alias of orderBookEntry for testing purposes
8-
func (o *orderbookUseCaseImpl) CreateFormattedLimitOrder(
8+
func (o *OrderbookUseCaseImpl) CreateFormattedLimitOrder(
99
poolID uint64,
1010
order orderbookdomain.Order,
1111
quoteAsset orderbookdomain.Asset,

0 commit comments

Comments
 (0)