Skip to content
This repository was archived by the owner on Oct 11, 2024. It is now read-only.

Commit 8123878

Browse files
authored
Merge pull request #892 from 0xProject/release/9.4.2
Release 9.4.2
2 parents c163356 + 09f254e commit 8123878

22 files changed

+1186
-849
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
This changelog is a work in progress and may contain notes for versions which have not actually been released. Check the [Releases](https://github.com/0xProject/0x-mesh/releases) page to see full release notes and more information about the latest released versions.
44

5+
## v9.4.2
6+
7+
### Bug fixes 🐞
8+
9+
- Fixes a bug that would cause Mesh nodes to crash upon receiving requests from legacy Mesh nodes [#888](https://github.com/0xProject/0x-mesh/pull/888).
10+
11+
512
## v9.4.1
613

714
### Bug fixes 🐞

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Version](https://img.shields.io/badge/version-9.4.1-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
1+
[![Version](https://img.shields.io/badge/version-9.4.2-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
22
[![Docs](https://img.shields.io/badge/docs-website-yellow.svg)](https://0x-org.gitbook.io/mesh)
33
[![Chat with us on Discord](https://img.shields.io/badge/chat-Discord-blueViolet.svg)](https://discord.gg/HF7fHwk)
44
[![Circle CI](https://img.shields.io/circleci/project/0xProject/0x-mesh/master.svg)](https://circleci.com/gh/0xProject/0x-mesh/tree/master)

RELEASE_CHANGELOG.md

-11
This file was deleted.

core/core.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const (
6060
estimatedNonPollingEthereumRPCRequestsPer24Hrs = 50000
6161
// logStatsInterval is how often to log stats for this node.
6262
logStatsInterval = 5 * time.Minute
63-
version = "9.4.1"
63+
version = "9.4.2"
6464
// ordersyncMinPeers is the minimum amount of peers to receive orders from
6565
// before considering the ordersync process finished.
6666
ordersyncMinPeers = 5

core/core_test.go

+162-80
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ package core
55
import (
66
"context"
77
"flag"
8+
"fmt"
9+
"math/big"
810
"sync"
911
"testing"
1012
"time"
@@ -92,11 +94,14 @@ func TestConfigChainIDAndRPCMatchDetection(t *testing.T) {
9294
wg.Wait()
9395
}
9496

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())
9799
}
98100

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+
}
100105
dataDir := "/tmp/test_node/" + uuid.New().String()
101106
config := Config{
102107
Verbosity: 2,
@@ -113,7 +118,7 @@ func newTestAppWithPrivateConfig(t *testing.T, pConfig privateConfig) *App {
113118
EthereumRPCMaxRequestsPer24HrUTC: 99999999999999,
114119
EthereumRPCMaxRequestsPerSecond: 99999999999999,
115120
MaxOrdersInStorage: 100000,
116-
CustomOrderFilter: "{}",
121+
CustomOrderFilter: customOrderFilter,
117122
}
118123
app, err := newWithPrivateConfig(config, pConfig)
119124
require.NoError(t, err)
@@ -177,100 +182,177 @@ func TestOrderSync(t *testing.T) {
177182
t.Skip("Serial tests (tests which cannot run in parallel) are disabled. You can enable them with the --serial flag")
178183
}
179184

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+
}
182233

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+
}
188240

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 = "{}"
202242

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+
}()
206262

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)
209273

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)
213276

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)
220309
require.NoError(t, err)
310+
if matches {
311+
filteredOrders = append(filteredOrders, order)
312+
}
221313
}
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)
236314

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
248330
}
249331
}
250332
if len(receivedAddedEvents) >= len(originalOrders) {
251333
break OrderEventLoop
252334
}
253335
}
254-
}
255336

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), "")
263340
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+
}
270351

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+
}
274356
}
275357

276358
func setupSubTest(t *testing.T) func(t *testing.T) {

core/message_handler.go

-7
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,6 @@ import (
1515
// Ensure that App implements p2p.MessageHandler.
1616
var _ p2p.MessageHandler = &App{}
1717

18-
func min(a int, b int) int {
19-
if a < b {
20-
return a
21-
}
22-
return b
23-
}
24-
2518
func (app *App) HandleMessages(ctx context.Context, messages []*p2p.Message) error {
2619
// First we validate the messages and decode them into orders.
2720
orders := []*zeroex.SignedOrder{}

0 commit comments

Comments
 (0)