6 "github.com/bytom/vapor/application/mov/common"
7 "github.com/bytom/vapor/application/mov/mock"
8 "github.com/bytom/vapor/protocol/bc"
9 "github.com/bytom/vapor/protocol/bc/types"
10 "github.com/bytom/vapor/protocol/validation"
13 func TestGenerateMatchedTxs(t *testing.T) {
14 btc2eth := &common.TradePair{FromAssetID: &mock.BTC, ToAssetID: &mock.ETH}
15 eth2btc := &common.TradePair{FromAssetID: &mock.ETH, ToAssetID: &mock.BTC}
16 eth2eos := &common.TradePair{FromAssetID: &mock.ETH, ToAssetID: &mock.EOS}
17 eos2btc := &common.TradePair{FromAssetID: &mock.EOS, ToAssetID: &mock.BTC}
21 tradePairs []*common.TradePair
22 initStoreOrders []*common.Order
23 wantMatchedTxs []*types.Tx
27 tradePairs: []*common.TradePair{btc2eth, eth2btc},
28 initStoreOrders: []*common.Order{
29 mock.Btc2EthOrders[0], mock.Btc2EthOrders[1],
30 mock.Eth2BtcOrders[0],
32 wantMatchedTxs: []*types.Tx{
37 desc: "partial matched",
38 tradePairs: []*common.TradePair{btc2eth, eth2btc},
39 initStoreOrders: []*common.Order{
40 mock.Btc2EthOrders[0], mock.Btc2EthOrders[1],
41 mock.Eth2BtcOrders[1],
43 wantMatchedTxs: []*types.Tx{
48 desc: "partial matched and continue to match",
49 tradePairs: []*common.TradePair{btc2eth, eth2btc},
50 initStoreOrders: []*common.Order{
51 mock.Btc2EthOrders[0], mock.Btc2EthOrders[1],
52 mock.Eth2BtcOrders[2],
54 wantMatchedTxs: []*types.Tx{
60 desc: "unable to match",
61 tradePairs: []*common.TradePair{btc2eth, eth2btc},
62 initStoreOrders: []*common.Order{
63 mock.Btc2EthOrders[1],
64 mock.Eth2BtcOrders[0],
66 wantMatchedTxs: []*types.Tx{},
70 tradePairs: []*common.TradePair{btc2eth, eth2eos, eos2btc},
71 initStoreOrders: []*common.Order{
72 mock.Btc2EthOrders[0], mock.Eth2EosOrders[0], mock.Eos2BtcOrders[0],
74 wantMatchedTxs: []*types.Tx{
79 desc: "multiple assets as a fee",
80 tradePairs: []*common.TradePair{btc2eth, eth2btc},
81 initStoreOrders: []*common.Order{
82 mock.Btc2EthOrders[0], mock.Eth2BtcOrders[3],
84 wantMatchedTxs: []*types.Tx{
90 for i, c := range cases {
91 movStore := mock.NewMovStore([]*common.TradePair{btc2eth, eth2btc}, c.initStoreOrders)
92 matchEngine := NewEngine(NewOrderBook(movStore, nil, nil), mock.RewardProgram)
93 var gotMatchedTxs []*types.Tx
94 for matchEngine.HasMatchedTx(c.tradePairs...) {
95 matchedTx, err := matchEngine.NextMatchedTx(c.tradePairs...)
100 gotMatchedTxs = append(gotMatchedTxs, matchedTx)
103 if len(c.wantMatchedTxs) != len(gotMatchedTxs) {
104 t.Errorf("#%d(%s) the length of got matched tx is not equals want matched tx", i, c.desc)
108 for j, gotMatchedTx := range gotMatchedTxs {
109 if _, err := validation.ValidateTx(gotMatchedTx.Tx, &bc.Block{BlockHeader: &bc.BlockHeader{Version: 1}}); err != nil {
113 c.wantMatchedTxs[j].Version = 1
114 byteData, err := c.wantMatchedTxs[j].MarshalText()
119 c.wantMatchedTxs[j].SerializedSize = uint64(len(byteData))
120 wantMatchedTx := types.NewTx(c.wantMatchedTxs[j].TxData)
121 if gotMatchedTx.ID != wantMatchedTx.ID {
122 t.Errorf("#%d(%s) the tx hash of got matched tx: %s is not equals want matched tx: %s", i, c.desc, gotMatchedTx.ID.String(), wantMatchedTx.ID.String())
128 func TestValidateTradePairs(t *testing.T) {
131 tradePairs []*common.TradePair
135 desc: "valid case of two trade pairs",
136 tradePairs: []*common.TradePair{
138 FromAssetID: &mock.BTC,
139 ToAssetID: &mock.ETH,
142 FromAssetID: &mock.ETH,
143 ToAssetID: &mock.BTC,
149 desc: "invalid case of two trade pairs",
150 tradePairs: []*common.TradePair{
152 FromAssetID: &mock.BTC,
153 ToAssetID: &mock.ETH,
156 FromAssetID: &mock.ETH,
157 ToAssetID: &mock.EOS,
163 desc: "valid case of three trade pairs",
164 tradePairs: []*common.TradePair{
166 FromAssetID: &mock.BTC,
167 ToAssetID: &mock.ETH,
170 FromAssetID: &mock.ETH,
171 ToAssetID: &mock.EOS,
174 FromAssetID: &mock.EOS,
175 ToAssetID: &mock.BTC,
181 desc: "invalid case of three trade pairs",
182 tradePairs: []*common.TradePair{
184 FromAssetID: &mock.BTC,
185 ToAssetID: &mock.ETH,
188 FromAssetID: &mock.ETH,
189 ToAssetID: &mock.BTC,
192 FromAssetID: &mock.BTC,
193 ToAssetID: &mock.BTC,
199 desc: "valid case 2 of three trade pairs",
200 tradePairs: []*common.TradePair{
202 FromAssetID: &mock.BTC,
203 ToAssetID: &mock.ETH,
206 FromAssetID: &mock.EOS,
207 ToAssetID: &mock.BTC,
210 FromAssetID: &mock.ETH,
211 ToAssetID: &mock.EOS,
218 for i, c := range cases {
219 err := validateTradePairs(c.tradePairs)
220 if c.wantError && err == nil {
221 t.Errorf("#%d(%s): want error, got no error", i, c.desc)
224 if !c.wantError && err != nil {
225 t.Errorf("#%d(%s): want no error, got error (%v)", i, c.desc, err)
230 func TestIsMatched(t *testing.T) {
233 orders []*common.Order
237 desc: "ratio is equals",
238 orders: []*common.Order{
240 FromAssetID: &mock.BTC,
241 ToAssetID: &mock.ETH,
242 RatioNumerator: 6250,
246 FromAssetID: &mock.ETH,
247 ToAssetID: &mock.BTC,
249 RatioDenominator: 6250,
255 desc: "ratio is equals, and numerator and denominator are multiples of the opposite",
256 orders: []*common.Order{
258 FromAssetID: &mock.BTC,
259 ToAssetID: &mock.ETH,
260 RatioNumerator: 6250,
264 FromAssetID: &mock.ETH,
265 ToAssetID: &mock.BTC,
267 RatioDenominator: 18750,
273 desc: "matched with a slight diff",
274 orders: []*common.Order{
276 FromAssetID: &mock.BTC,
277 ToAssetID: &mock.ETH,
278 RatioNumerator: 62500000000000000,
279 RatioDenominator: 30000000000001,
282 FromAssetID: &mock.ETH,
283 ToAssetID: &mock.BTC,
285 RatioDenominator: 6250,
291 desc: "not matched with a slight diff",
292 orders: []*common.Order{
294 FromAssetID: &mock.BTC,
295 ToAssetID: &mock.ETH,
296 RatioNumerator: 62500000000000001,
297 RatioDenominator: 30000000000000,
300 FromAssetID: &mock.ETH,
301 ToAssetID: &mock.BTC,
303 RatioDenominator: 6250,
309 desc: "ring matched",
310 orders: []*common.Order{
312 FromAssetID: &mock.BTC,
313 ToAssetID: &mock.ETH,
314 RatioNumerator: 2000000003,
315 RatioDenominator: 100000001,
318 FromAssetID: &mock.ETH,
319 ToAssetID: &mock.EOS,
320 RatioNumerator: 400000000001,
321 RatioDenominator: 2000000003,
324 FromAssetID: &mock.EOS,
325 ToAssetID: &mock.BTC,
326 RatioNumerator: 100000001,
327 RatioDenominator: 400000000001,
333 desc: "ring matched with a slight diff",
334 orders: []*common.Order{
336 FromAssetID: &mock.BTC,
337 ToAssetID: &mock.ETH,
338 RatioNumerator: 2000000003,
339 RatioDenominator: 100000001,
342 FromAssetID: &mock.ETH,
343 ToAssetID: &mock.EOS,
344 RatioNumerator: 400000000001,
345 RatioDenominator: 2000000003,
348 FromAssetID: &mock.EOS,
349 ToAssetID: &mock.BTC,
350 RatioNumerator: 100000000,
351 RatioDenominator: 400000000001,
357 desc: "ring fail matched with a slight diff",
358 orders: []*common.Order{
360 FromAssetID: &mock.BTC,
361 ToAssetID: &mock.ETH,
362 RatioNumerator: 2000000003,
363 RatioDenominator: 100000001,
366 FromAssetID: &mock.ETH,
367 ToAssetID: &mock.EOS,
368 RatioNumerator: 400000000001,
369 RatioDenominator: 2000000003,
372 FromAssetID: &mock.EOS,
373 ToAssetID: &mock.BTC,
374 RatioNumerator: 100000002,
375 RatioDenominator: 400000000001,
382 for i, c := range cases {
383 gotMatched := IsMatched(c.orders)
384 if gotMatched != c.wantMatched {
385 t.Errorf("#%d(%s) got matched:%v, want matched:%v", i, c.desc, gotMatched, c.wantMatched)