From 75c0efa76341e93d6289480559c0881eefad14b7 Mon Sep 17 00:00:00 2001 From: paladz <453256728@qq.com> Date: Thu, 13 Feb 2020 19:59:04 +0800 Subject: [PATCH] fix add order bug --- application/mov/match/order_book.go | 10 ++--- application/mov/match/order_book_test.go | 76 ++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/application/mov/match/order_book.go b/application/mov/match/order_book.go index e7792897..91638238 100644 --- a/application/mov/match/order_book.go +++ b/application/mov/match/order_book.go @@ -6,7 +6,6 @@ import ( "github.com/bytom/vapor/application/mov/common" "github.com/bytom/vapor/application/mov/database" - "github.com/bytom/vapor/errors" ) // OrderBook is used to handle the mov orders in memory like stack @@ -62,11 +61,12 @@ func NewOrderBook(movStore database.MovStore, arrivalAddOrders, arrivalDelOrders func (o *OrderBook) AddOrder(order *common.Order) error { tradePairKey := order.TradePair().Key() orders := o.getArrivalAddOrders(tradePairKey) - if len(orders) > 0 && order.Cmp(orders[len(orders)-1]) > 0 { - return errors.New("rate of order must less than the min order in order table") - } - + // use binary search to find the insert position + i := sort.Search(len(orders), func(i int) bool { return order.Cmp(orders[i]) > 0 }) orders = append(orders, order) + copy(orders[i+1:], orders[i:]) + orders[i] = order + o.arrivalAddOrders.Store(tradePairKey, orders) return nil } diff --git a/application/mov/match/order_book_test.go b/application/mov/match/order_book_test.go index 466a9530..4b3fa8db 100644 --- a/application/mov/match/order_book_test.go +++ b/application/mov/match/order_book_test.go @@ -300,3 +300,79 @@ func TestPeekArrivalOrder(t *testing.T) { } } } + +func TestAddOrder(t *testing.T) { + cases := []struct { + initOrders []*common.Order + wantOrders []*common.Order + addOrder *common.Order + }{ + { + initOrders: []*common.Order{}, + addOrder: &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 53, RatioDenominator: 1}, + wantOrders: []*common.Order{ + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 53, RatioDenominator: 1}, + }, + }, + { + initOrders: []*common.Order{ + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 51, RatioDenominator: 1}, + }, + addOrder: &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 50, RatioDenominator: 1}, + wantOrders: []*common.Order{ + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 51, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 50, RatioDenominator: 1}, + }, + }, + { + initOrders: []*common.Order{ + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 50, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 51, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 52, RatioDenominator: 1}, + }, + addOrder: &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 53, RatioDenominator: 1}, + wantOrders: []*common.Order{ + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 53, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 52, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 51, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 50, RatioDenominator: 1}, + }, + }, + { + initOrders: []*common.Order{ + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 50, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 51, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 52, RatioDenominator: 1}, + }, + addOrder: &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 49, RatioDenominator: 1}, + wantOrders: []*common.Order{ + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 52, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 51, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 50, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 49, RatioDenominator: 1}, + }, + }, + { + initOrders: []*common.Order{ + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 52, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 51, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 49, RatioDenominator: 1}, + }, + addOrder: &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 50, RatioDenominator: 1}, + wantOrders: []*common.Order{ + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 52, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 51, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 50, RatioDenominator: 1}, + &common.Order{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH, RatioNumerator: 49, RatioDenominator: 1}, + }, + }, + } + + for i, c := range cases { + orderBook := NewOrderBook(mock.NewMovStore(nil, nil), c.initOrders, nil) + orderBook.AddOrder(c.addOrder) + if gotOrders := orderBook.getArrivalAddOrders(btc2eth.Key()); !testutil.DeepEqual(gotOrders, c.wantOrders) { + t.Fatalf("#%d: the gotOrders(%v) is differnt than wantOrders(%v)", i, gotOrders, c.wantOrders) + } + } +} -- 2.11.0