@@ -5,6 +5,8 @@ package core
5
5
import (
6
6
"context"
7
7
"flag"
8
+ "fmt"
9
+ "math/big"
8
10
"sync"
9
11
"testing"
10
12
"time"
@@ -92,11 +94,14 @@ func TestConfigChainIDAndRPCMatchDetection(t *testing.T) {
92
94
wg .Wait ()
93
95
}
94
96
95
- func newTestApp (t * testing.T ) * App {
96
- return newTestAppWithPrivateConfig (t , defaultPrivateConfig ())
97
+ func newTestApp (t * testing.T , ctx context. Context ) * App {
98
+ return newTestAppWithPrivateConfig (t , ctx , defaultOrderFilter , defaultPrivateConfig ())
97
99
}
98
100
99
- func newTestAppWithPrivateConfig (t * testing.T , pConfig privateConfig ) * App {
101
+ func newTestAppWithPrivateConfig (t * testing.T , ctx context.Context , customOrderFilter string , pConfig privateConfig ) * App {
102
+ if customOrderFilter == "" {
103
+ customOrderFilter = defaultOrderFilter
104
+ }
100
105
dataDir := "/tmp/test_node/" + uuid .New ().String ()
101
106
config := Config {
102
107
Verbosity : 2 ,
@@ -113,7 +118,7 @@ func newTestAppWithPrivateConfig(t *testing.T, pConfig privateConfig) *App {
113
118
EthereumRPCMaxRequestsPer24HrUTC : 99999999999999 ,
114
119
EthereumRPCMaxRequestsPerSecond : 99999999999999 ,
115
120
MaxOrdersInStorage : 100000 ,
116
- CustomOrderFilter : "{}" ,
121
+ CustomOrderFilter : customOrderFilter ,
117
122
}
118
123
app , err := newWithPrivateConfig (config , pConfig )
119
124
require .NoError (t , err )
@@ -177,100 +182,177 @@ func TestOrderSync(t *testing.T) {
177
182
t .Skip ("Serial tests (tests which cannot run in parallel) are disabled. You can enable them with the --serial flag" )
178
183
}
179
184
180
- teardownSubTest := setupSubTest (t )
181
- defer teardownSubTest (t )
185
+ testCases := []ordersyncTestCase {
186
+ {
187
+ name : "FilteredPaginationSubprotocol version 0" ,
188
+ pConfig : privateConfig {
189
+ paginationSubprotocolPerPage : 10 ,
190
+ },
191
+ },
192
+ {
193
+ name : "FilteredPaginationSubprotocol version 1" ,
194
+ pConfig : privateConfig {
195
+ paginationSubprotocolPerPage : 10 ,
196
+ },
197
+ },
198
+ {
199
+ name : "FilteredPaginationSubprotocol version 1 and version 0" ,
200
+ pConfig : privateConfig {
201
+ paginationSubprotocolPerPage : 10 ,
202
+ },
203
+ },
204
+ {
205
+ name : "makerAssetAmount orderfilter - match all orders" ,
206
+ customOrderFilter : `{"properties":{"makerAssetAmount":{"pattern":"^1$","type":"string"}}}` ,
207
+ orderOptionsForIndex : func (_ int ) []orderopts.Option {
208
+ return []orderopts.Option {orderopts .MakerAssetAmount (big .NewInt (1 ))}
209
+ },
210
+ pConfig : privateConfig {
211
+ paginationSubprotocolPerPage : 10 ,
212
+ },
213
+ },
214
+ {
215
+ name : "makerAssetAmount OrderFilter - matches one order" ,
216
+ customOrderFilter : `{"properties":{"makerAssetAmount":{"pattern":"^1$","type":"string"}}}` ,
217
+ orderOptionsForIndex : func (i int ) []orderopts.Option {
218
+ if i == 0 {
219
+ return []orderopts.Option {orderopts .MakerAssetAmount (big .NewInt (1 ))}
220
+ }
221
+ return []orderopts.Option {}
222
+ },
223
+ pConfig : privateConfig {
224
+ paginationSubprotocolPerPage : 10 ,
225
+ },
226
+ },
227
+ }
228
+ for i , testCase := range testCases {
229
+ testCaseName := fmt .Sprintf ("%s (test case %d)" , testCase .name , i )
230
+ t .Run (testCaseName , runOrdersyncTestCase (t , testCase ))
231
+ }
232
+ }
182
233
183
- // Set up two Mesh nodes. originalNode starts with some orders. newNode enters
184
- // the network without any orders.
185
- ctx , cancel := context .WithTimeout (context .Background (), 60 * time .Second )
186
- defer cancel ()
187
- wg := & sync.WaitGroup {}
234
+ type ordersyncTestCase struct {
235
+ name string
236
+ customOrderFilter string
237
+ orderOptionsForIndex func (int ) []orderopts.Option
238
+ pConfig privateConfig
239
+ }
188
240
189
- perPage := 10
190
- pConfig := privateConfig {
191
- paginationSubprotocolPerPage : perPage ,
192
- }
193
- originalNode := newTestAppWithPrivateConfig (t , pConfig )
194
- wg .Add (1 )
195
- go func () {
196
- defer wg .Done ()
197
- if err := originalNode .Start (ctx ); err != nil && err != context .Canceled {
198
- // context.Canceled is expected. For any other error, fail the test.
199
- require .NoError (t , err )
200
- }
201
- }()
241
+ const defaultOrderFilter = "{}"
202
242
203
- // Manually add some orders to originalNode.
204
- orderOptions := scenario .OptionsForAll (orderopts .SetupMakerState (true ))
205
- originalOrders := scenario .NewSignedTestOrdersBatch (t , perPage * 3 + 1 , orderOptions )
243
+ func runOrdersyncTestCase (t * testing.T , testCase ordersyncTestCase ) func (t * testing.T ) {
244
+ return func (t * testing.T ) {
245
+ teardownSubTest := setupSubTest (t )
246
+ defer teardownSubTest (t )
247
+
248
+ // Set up two Mesh nodes. originalNode starts with some orders. newNode enters
249
+ // the network without any orders.
250
+ ctx , cancel := context .WithTimeout (context .Background (), 60 * time .Second )
251
+ defer cancel ()
252
+ wg := & sync.WaitGroup {}
253
+ originalNode := newTestAppWithPrivateConfig (t , ctx , defaultOrderFilter , testCase .pConfig )
254
+ wg .Add (1 )
255
+ go func () {
256
+ defer wg .Done ()
257
+ if err := originalNode .Start (ctx ); err != nil && err != context .Canceled {
258
+ // context.Canceled is expected. For any other error, fail the test.
259
+ panic (fmt .Sprintf ("%s %s" , testCase .name , err ))
260
+ }
261
+ }()
206
262
207
- // We have to wait for latest block to be processed by the Mesh node.
208
- time .Sleep (blockProcessingWaitTime )
263
+ // Manually add some orders to originalNode.
264
+ orderOptionsForIndex := func (i int ) []orderopts.Option {
265
+ orderOptions := []orderopts.Option {orderopts .SetupMakerState (true )}
266
+ if testCase .orderOptionsForIndex != nil {
267
+ return append (testCase .orderOptionsForIndex (i ), orderOptions ... )
268
+ }
269
+ return orderOptions
270
+ }
271
+ numOrders := testCase .pConfig .paginationSubprotocolPerPage * 3 + 1
272
+ originalOrders := scenario .NewSignedTestOrdersBatch (t , numOrders , orderOptionsForIndex )
209
273
210
- results , err := originalNode .orderWatcher .ValidateAndStoreValidOrders (ctx , originalOrders , true , constants .TestChainID )
211
- require .NoError (t , err )
212
- require .Empty (t , results .Rejected , "tried to add orders but some were invalid: \n %s\n " , spew .Sdump (results ))
274
+ // We have to wait for latest block to be processed by the Mesh node.
275
+ time .Sleep (blockProcessingWaitTime )
213
276
214
- newNode := newTestApp (t )
215
- wg .Add (1 )
216
- go func () {
217
- defer wg .Done ()
218
- if err := newNode .Start (ctx ); err != nil && err != context .Canceled {
219
- // context.Canceled is expected. For any other error, fail the test.
277
+ results , err := originalNode .orderWatcher .ValidateAndStoreValidOrders (ctx , originalOrders , true , constants .TestChainID )
278
+ require .NoError (t , err )
279
+ require .Empty (t , results .Rejected , "tried to add orders but some were invalid: \n %s\n " , spew .Sdump (results ))
280
+
281
+ newNode := newTestAppWithPrivateConfig (t , ctx , testCase .customOrderFilter , defaultPrivateConfig ())
282
+ wg .Add (1 )
283
+ go func () {
284
+ defer wg .Done ()
285
+ if err := newNode .Start (ctx ); err != nil && err != context .Canceled {
286
+ // context.Canceled is expected. For any other error, fail the test.
287
+ panic (fmt .Sprintf ("%s %s" , testCase .name , err ))
288
+ }
289
+ }()
290
+ <- newNode .started
291
+
292
+ orderEventsChan := make (chan []* zeroex.OrderEvent )
293
+ orderEventsSub := newNode .SubscribeToOrderEvents (orderEventsChan )
294
+ defer orderEventsSub .Unsubscribe ()
295
+
296
+ // Connect the two nodes *after* adding orders to one of them. This should
297
+ // trigger the ordersync protocol.
298
+ err = originalNode .AddPeer (peer.AddrInfo {
299
+ ID : newNode .node .ID (),
300
+ Addrs : newNode .node .Multiaddrs (),
301
+ })
302
+ require .NoError (t , err )
303
+
304
+ // Only the orders that satisfy the new node's orderfilter should
305
+ // be received during ordersync.
306
+ filteredOrders := []* zeroex.SignedOrder {}
307
+ for _ , order := range originalOrders {
308
+ matches , err := newNode .orderFilter .MatchOrder (order )
220
309
require .NoError (t , err )
310
+ if matches {
311
+ filteredOrders = append (filteredOrders , order )
312
+ }
221
313
}
222
- }()
223
- <- newNode .started
224
-
225
- orderEventsChan := make (chan []* zeroex.OrderEvent )
226
- orderEventsSub := newNode .SubscribeToOrderEvents (orderEventsChan )
227
- defer orderEventsSub .Unsubscribe ()
228
-
229
- // Connect the two nodes *after* adding orders to one of them. This should
230
- // trigger the ordersync protocol.
231
- err = originalNode .AddPeer (peer.AddrInfo {
232
- ID : newNode .node .ID (),
233
- Addrs : newNode .node .Multiaddrs (),
234
- })
235
- require .NoError (t , err )
236
314
237
- // Wait for newNode to get the orders via ordersync.
238
- receivedAddedEvents := []* zeroex.OrderEvent {}
239
- OrderEventLoop:
240
- for {
241
- select {
242
- case <- ctx .Done ():
243
- t .Fatalf ("timed out waiting for %d order added events (received %d so far)" , len (originalOrders ), len (receivedAddedEvents ))
244
- case orderEvents := <- orderEventsChan :
245
- for _ , orderEvent := range orderEvents {
246
- if orderEvent .EndState == zeroex .ESOrderAdded {
247
- receivedAddedEvents = append (receivedAddedEvents , orderEvent )
315
+ // Wait for newNode to get the orders via ordersync.
316
+ receivedAddedEvents := []* zeroex.OrderEvent {}
317
+ OrderEventLoop:
318
+ for {
319
+ select {
320
+ case <- ctx .Done ():
321
+ t .Fatalf ("timed out waiting for %d order added events (received %d so far)" , len (originalOrders ), len (receivedAddedEvents ))
322
+ case orderEvents := <- orderEventsChan :
323
+ for _ , orderEvent := range orderEvents {
324
+ if orderEvent .EndState == zeroex .ESOrderAdded {
325
+ receivedAddedEvents = append (receivedAddedEvents , orderEvent )
326
+ }
327
+ }
328
+ if len (receivedAddedEvents ) >= len (filteredOrders ) {
329
+ break OrderEventLoop
248
330
}
249
331
}
250
332
if len (receivedAddedEvents ) >= len (originalOrders ) {
251
333
break OrderEventLoop
252
334
}
253
335
}
254
- }
255
336
256
- // Test that the orders are actually in the database and are returned by
257
- // GetOrders.
258
- newNodeOrdersResp , err := newNode .GetOrders (0 , len (originalOrders ), "" )
259
- require .NoError (t , err )
260
- assert .Len (t , newNodeOrdersResp .OrdersInfos , len (originalOrders ), "new node should have %d orders" , len (originalOrders ))
261
- for _ , expectedOrder := range originalOrders {
262
- orderHash , err := expectedOrder .ComputeOrderHash ()
337
+ // Test that the orders are actually in the database and are returned by
338
+ // GetOrders.
339
+ newNodeOrdersResp , err := newNode .GetOrders (0 , len (filteredOrders ), "" )
263
340
require .NoError (t , err )
264
- expectedOrder .ResetHash ()
265
- var dbOrder meshdb.Order
266
- require .NoError (t , newNode .db .Orders .FindByID (orderHash .Bytes (), & dbOrder ))
267
- actualOrder := dbOrder .SignedOrder
268
- assert .Equal (t , expectedOrder , actualOrder , "correct order was not stored in new node database" )
269
- }
341
+ assert .Len (t , newNodeOrdersResp .OrdersInfos , len (filteredOrders ), "new node should have %d orders" , len (originalOrders ))
342
+ for _ , expectedOrder := range filteredOrders {
343
+ orderHash , err := expectedOrder .ComputeOrderHash ()
344
+ require .NoError (t , err )
345
+ expectedOrder .ResetHash ()
346
+ var dbOrder meshdb.Order
347
+ require .NoError (t , newNode .db .Orders .FindByID (orderHash .Bytes (), & dbOrder ))
348
+ actualOrder := dbOrder .SignedOrder
349
+ assert .Equal (t , expectedOrder , actualOrder , "correct order was not stored in new node database" )
350
+ }
270
351
271
- // Wait for nodes to exit without error.
272
- cancel ()
273
- wg .Wait ()
352
+ // Wait for nodes to exit without error.
353
+ cancel ()
354
+ wg .Wait ()
355
+ }
274
356
}
275
357
276
358
func setupSubTest (t * testing.T ) func (t * testing.T ) {
0 commit comments