10 "github.com/stretchr/testify/require"
12 "github.com/bytom/vapor/application/mov/common"
13 "github.com/bytom/vapor/database/leveldb"
14 dbm "github.com/bytom/vapor/database/leveldb"
15 "github.com/bytom/vapor/protocol/bc"
16 "github.com/bytom/vapor/protocol/bc/types"
17 "github.com/bytom/vapor/testutil"
21 assetID1 = &bc.AssetID{V0: 1}
22 assetID2 = &bc.AssetID{V0: 2}
23 assetID3 = &bc.AssetID{V0: 3}
24 assetID4 = &bc.AssetID{V0: 4}
25 assetID5 = &bc.AssetID{V0: 5}
26 assetID6 = &bc.AssetID{V0: 6}
27 assetID7 = &bc.AssetID{V0: 7}
28 assetID8 = &bc.AssetID{V0: 8}
30 orderProgram = testutil.MustDecodeHexString("0020184e1cc4ee4845023888810a79eed7a42c02c544cf2c61ceac05e176d575bd4603ed4e0e0210272200204775b9e167e2c1ffe57ae3e5088af69e518be010529b5fdadf4be97656084eec20a3e21b55f44403884457166ad5847fdb5489512ba9611eee466efb9f94319143")
31 sellerProgram = testutil.MustDecodeHexString("00204775b9e167e2c1ffe57ae3e5088af69e518be010529b5fdadf4be97656084eec")
33 mockOrders = []*common.Order{
35 FromAssetID: assetID1,
37 RatioNumerator: 100090,
38 RatioDenominator: 100000,
39 Utxo: &common.MovUtxo{
40 SourceID: &bc.Hash{V0: 21},
43 ControlProgram: orderProgram,
45 SellerProgram: sellerProgram,
48 FromAssetID: assetID1,
51 RatioDenominator: 100000,
52 Utxo: &common.MovUtxo{
53 SourceID: &bc.Hash{V0: 22},
56 ControlProgram: orderProgram,
58 SellerProgram: sellerProgram,
61 FromAssetID: assetID1,
64 RatioDenominator: 100000,
65 Utxo: &common.MovUtxo{
66 SourceID: &bc.Hash{V0: 23},
69 ControlProgram: orderProgram,
71 SellerProgram: sellerProgram,
74 FromAssetID: assetID1,
77 RatioDenominator: 100000,
78 Utxo: &common.MovUtxo{
79 SourceID: &bc.Hash{V0: 13},
82 ControlProgram: orderProgram,
84 SellerProgram: sellerProgram,
87 FromAssetID: assetID1,
90 RatioDenominator: 100000,
91 Utxo: &common.MovUtxo{
92 SourceID: &bc.Hash{V0: 24},
95 ControlProgram: orderProgram,
97 SellerProgram: sellerProgram,
100 FromAssetID: assetID1,
103 RatioDenominator: 100000,
104 Utxo: &common.MovUtxo{
105 SourceID: &bc.Hash{V0: 24},
108 ControlProgram: orderProgram,
110 SellerProgram: sellerProgram,
113 FromAssetID: assetID1,
116 RatioDenominator: 100000,
117 Utxo: &common.MovUtxo{
118 SourceID: &bc.Hash{V0: 25},
121 ControlProgram: orderProgram,
123 SellerProgram: sellerProgram,
126 FromAssetID: assetID1,
129 RatioDenominator: 100000,
130 Utxo: &common.MovUtxo{
131 SourceID: &bc.Hash{V0: 26},
134 ControlProgram: orderProgram,
136 SellerProgram: sellerProgram,
139 FromAssetID: assetID1,
142 RatioDenominator: 100000,
143 Utxo: &common.MovUtxo{
144 SourceID: &bc.Hash{V0: 1},
147 ControlProgram: orderProgram,
149 SellerProgram: sellerProgram,
152 FromAssetID: assetID1,
155 RatioDenominator: 100000,
156 Utxo: &common.MovUtxo{
157 SourceID: &bc.Hash{V0: 2},
160 ControlProgram: orderProgram,
162 SellerProgram: sellerProgram,
165 FromAssetID: assetID3,
168 RatioDenominator: 100000,
169 Utxo: &common.MovUtxo{
170 SourceID: &bc.Hash{V0: 33},
173 ControlProgram: orderProgram,
175 SellerProgram: sellerProgram,
178 FromAssetID: assetID4,
181 RatioDenominator: 100000,
182 Utxo: &common.MovUtxo{
183 SourceID: &bc.Hash{V0: 34},
186 ControlProgram: orderProgram,
188 SellerProgram: sellerProgram,
191 FromAssetID: assetID4,
194 RatioDenominator: 100000,
195 Utxo: &common.MovUtxo{
196 SourceID: &bc.Hash{V0: 36},
199 ControlProgram: orderProgram,
201 SellerProgram: sellerProgram,
204 FromAssetID: assetID5,
207 RatioDenominator: 100000,
208 Utxo: &common.MovUtxo{
209 SourceID: &bc.Hash{V0: 37},
212 ControlProgram: orderProgram,
214 SellerProgram: sellerProgram,
217 FromAssetID: assetID6,
220 RatioDenominator: 100000,
221 Utxo: &common.MovUtxo{
222 SourceID: &bc.Hash{V0: 38},
225 ControlProgram: orderProgram,
227 SellerProgram: sellerProgram,
232 func TestGetAssetIDFromTradePairKey(t *testing.T) {
233 b := calcTradePairKey(assetID1, assetID2)
234 gotA := getAssetIDFromTradePairKey(b, fromAssetIDPos)
235 gotB := getAssetIDFromTradePairKey(b, toAssetIDPos)
237 if *gotA != *assetID1 {
238 t.Fatalf("got wrong from asset id got %s, want %s", gotA.String(), assetID1.String())
241 if *gotB != *assetID2 {
242 t.Fatalf("got wrong to asset id got %s, want %s", gotB.String(), assetID2.String())
246 func TestSortOrderKey(t *testing.T) {
247 dirname, err := ioutil.TempDir("", "db_common_test")
250 db, err := leveldb.NewGoLevelDB("testdb", dirname)
257 os.RemoveAll(dirname)
260 type expectedData struct {
266 orders []*common.Order
270 orders: []*common.Order{
272 FromAssetID: &bc.AssetID{V0: 1},
273 ToAssetID: &bc.AssetID{V0: 0},
274 RatioNumerator: 100090,
275 RatioDenominator: 100000,
276 Utxo: &common.MovUtxo{
277 SourceID: &bc.Hash{V0: 21},
280 ControlProgram: []byte("aa"),
284 FromAssetID: &bc.AssetID{V0: 1},
285 ToAssetID: &bc.AssetID{V0: 0},
287 RatioDenominator: 100000,
288 Utxo: &common.MovUtxo{
289 SourceID: &bc.Hash{V0: 22},
292 ControlProgram: []byte("aa"),
296 FromAssetID: &bc.AssetID{V0: 1},
297 ToAssetID: &bc.AssetID{V0: 0},
299 RatioDenominator: 100000,
300 Utxo: &common.MovUtxo{
301 SourceID: &bc.Hash{V0: 23},
304 ControlProgram: []byte("aa"),
308 FromAssetID: &bc.AssetID{V0: 1},
309 ToAssetID: &bc.AssetID{V0: 0},
311 RatioDenominator: 100000,
312 Utxo: &common.MovUtxo{
313 SourceID: &bc.Hash{V0: 13},
316 ControlProgram: []byte("aa"),
320 FromAssetID: &bc.AssetID{V0: 1},
321 ToAssetID: &bc.AssetID{V0: 0},
323 RatioDenominator: 100000,
324 Utxo: &common.MovUtxo{
325 SourceID: &bc.Hash{V0: 24},
328 ControlProgram: []byte("aa"),
332 FromAssetID: &bc.AssetID{V0: 1},
333 ToAssetID: &bc.AssetID{V0: 0},
335 RatioDenominator: 100000,
336 Utxo: &common.MovUtxo{
337 SourceID: &bc.Hash{V0: 25},
340 ControlProgram: []byte("aa"),
344 FromAssetID: &bc.AssetID{V0: 1},
345 ToAssetID: &bc.AssetID{V0: 0},
347 RatioDenominator: 100000,
348 Utxo: &common.MovUtxo{
349 SourceID: &bc.Hash{V0: 26},
352 ControlProgram: []byte("aa"),
356 FromAssetID: &bc.AssetID{V0: 1},
357 ToAssetID: &bc.AssetID{V0: 0},
359 RatioDenominator: 100000,
360 Utxo: &common.MovUtxo{
361 SourceID: &bc.Hash{V0: 27},
364 ControlProgram: []byte("aa"),
368 FromAssetID: &bc.AssetID{V0: 1},
369 ToAssetID: &bc.AssetID{V0: 0},
371 RatioDenominator: 100000,
372 Utxo: &common.MovUtxo{
373 SourceID: &bc.Hash{V0: 24},
376 ControlProgram: []byte("aa"),
380 FromAssetID: &bc.AssetID{V0: 1},
381 ToAssetID: &bc.AssetID{V0: 0},
383 RatioDenominator: 100000,
384 Utxo: &common.MovUtxo{
385 SourceID: &bc.Hash{V0: 25},
388 ControlProgram: []byte("aa"),
392 FromAssetID: &bc.AssetID{V0: 1},
393 ToAssetID: &bc.AssetID{V0: 0},
395 RatioDenominator: 100000,
396 Utxo: &common.MovUtxo{
397 SourceID: &bc.Hash{V0: 26},
400 ControlProgram: []byte("aa"),
404 FromAssetID: &bc.AssetID{V0: 1},
405 ToAssetID: &bc.AssetID{V0: 0},
407 RatioDenominator: 100000,
408 Utxo: &common.MovUtxo{
409 SourceID: &bc.Hash{V0: 26},
412 ControlProgram: []byte("aa"),
416 FromAssetID: &bc.AssetID{V0: 1},
417 ToAssetID: &bc.AssetID{V0: 0},
419 RatioDenominator: 100000,
420 Utxo: &common.MovUtxo{
421 SourceID: &bc.Hash{V0: 27},
424 ControlProgram: []byte("aa"),
428 FromAssetID: &bc.AssetID{V0: 1},
429 ToAssetID: &bc.AssetID{V0: 0},
431 RatioDenominator: 100000,
432 Utxo: &common.MovUtxo{
433 SourceID: &bc.Hash{V0: 28},
436 ControlProgram: []byte("aa"),
440 FromAssetID: &bc.AssetID{V0: 1},
441 ToAssetID: &bc.AssetID{V0: 0},
443 RatioDenominator: 100000,
444 Utxo: &common.MovUtxo{
445 SourceID: &bc.Hash{V0: 29},
448 ControlProgram: []byte("aa"),
452 FromAssetID: &bc.AssetID{V0: 1},
453 ToAssetID: &bc.AssetID{V0: 0},
455 RatioDenominator: 100000,
456 Utxo: &common.MovUtxo{
457 SourceID: &bc.Hash{V0: 30},
460 ControlProgram: []byte("aa"),
464 FromAssetID: &bc.AssetID{V0: 1},
465 ToAssetID: &bc.AssetID{V0: 0},
467 RatioDenominator: 100000,
468 Utxo: &common.MovUtxo{
469 SourceID: &bc.Hash{V0: 31},
472 ControlProgram: []byte("aa"),
476 FromAssetID: &bc.AssetID{V0: 1},
477 ToAssetID: &bc.AssetID{V0: 0},
478 RatioNumerator: 9999999521,
479 RatioDenominator: 10000,
480 Utxo: &common.MovUtxo{
481 SourceID: &bc.Hash{V0: 32},
484 ControlProgram: []byte("aa"),
488 FromAssetID: &bc.AssetID{V0: 1},
489 ToAssetID: &bc.AssetID{V0: 0},
490 RatioNumerator: 8888887954,
491 RatioDenominator: 10000,
492 Utxo: &common.MovUtxo{
493 SourceID: &bc.Hash{V0: 33},
496 ControlProgram: []byte("aa"),
500 want: []expectedData{
503 utxoHash: "f1b85307cf1f4eb6b193b6fc289413fdbb12bc362ced399762589b016e54dd02",
507 utxoHash: "49ef60af0f24962ed129a73142048ed0cb589041c629353932e3c3e0a4e822ba",
511 utxoHash: "67b2ac6ea71b271e72836e162811866f291ed2fab106c43519ca0c94ef8a5dce",
515 utxoHash: "47ff45b7b530512142981c2cee82faad63d6c9e7ffed0e72c3e42668f13b296f",
519 utxoHash: "b750d0b95f38043362c8335f242f97cfd3e1cada8fd171b914471a16cc0f14c6",
523 utxoHash: "04386ef57f0ca1be0a9be46c413900adbc0ab1e90e773959924aa73ca62edf64",
527 utxoHash: "c0fe6227c50da350a5e7b4ff85c18e9c901c323521067b9142acd128cf13ae82",
531 utxoHash: "47ff45b7b530512142981c2cee82faad63d6c9e7ffed0e72c3e42668f13b296f",
535 utxoHash: "bc92df1cbd20c98b0d18c9d93422a770849235867522a08e492196d16ed0a422",
539 utxoHash: "0cc0ded6fb337a3c5e6e4d008d6167dc58bdede43713898e914d65cda3b8499a",
543 utxoHash: "14b51a6103f75d9cacdf0f9551467588c687ed3b029e25c646d276720569e227",
547 utxoHash: "1fa9fae83d0a5401a4e92f80636966486e763eecca588aa11dff02b415320602",
551 utxoHash: "6687d18ddbe4e7381a844e393ca3032a412285c9da6988eff182106e28ba09ca",
555 utxoHash: "841b1de7c871dfe6e2d1886809d9ae12ec45e570233b03879305232b096fda43",
559 utxoHash: "a4bc534c267d35a9eafc25cd66e0cb270a2537a51186605b7f7591bc567ab4c6",
563 utxoHash: "fdedf4117def659e07cc8a8ca318d21ae577a05e1a0197844b54d493bdae5854",
567 utxoHash: "20be3bd2d406bb7fe6627b32768fb2073e997b962a4badfa4384210fed2ab9c6",
571 utxoHash: "72192f56b9525c74c6a9f0419563bc0da76b0f3d6e89d9decdb6e67786ac3909",
575 utxoHash: "7886844334659b4feffc41528cf81192925d3aa4a5ccb3652200b9073b7d47c3",
581 for i, c := range cases {
582 for _, order := range c.orders {
583 key := calcOrderKey(order.FromAssetID, order.ToAssetID, order.UTXOHash(), order.Rate())
584 data, err := json.Marshal(order.Utxo)
589 db.SetSync(key, data)
592 got := []expectedData{}
593 itr := db.IteratorPrefixWithStart(nil, nil, false)
596 pos := len(ordersPrefix) + assetIDLen*2
598 copy(b[:], key[pos+8:])
599 utxoHash := bc.NewHash(b)
601 got = append(got, expectedData{
602 rate: getRateFromOrderKey(key),
603 utxoHash: utxoHash.String(),
608 if !testutil.DeepEqual(c.want, got) {
609 t.Errorf("case %v: got recovery status, got: %v, want: %v.", i, got, c.want)
614 func TestMovStore(t *testing.T) {
617 beforeOrders []*common.Order
618 beforeTradePairs []*common.TradePair
619 beforeDBStatus *common.MovDatabaseState
620 addOrders []*common.Order
621 delOrders []*common.Order
622 blockHeader *types.BlockHeader
623 wantOrders []*common.Order
624 wantTradePairs []*common.TradePair
625 wantDBState *common.MovDatabaseState
629 addOrders: []*common.Order{
639 blockHeader: &types.BlockHeader{Height: 1, PreviousBlockHash: bc.Hash{V0: 524821139490765641, V1: 2484214155808702787, V2: 9108473449351508820, V3: 7972721253564512122}},
640 wantOrders: []*common.Order{
650 wantTradePairs: []*common.TradePair{
651 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 8},
653 wantDBState: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
656 desc: "del some order",
657 beforeOrders: []*common.Order{
667 beforeTradePairs: []*common.TradePair{
669 FromAssetID: assetID1,
674 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
675 delOrders: []*common.Order{
680 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
681 wantOrders: []*common.Order{
688 wantTradePairs: []*common.TradePair{
689 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 5},
691 wantDBState: &common.MovDatabaseState{Height: 2, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
694 desc: "del all order",
695 beforeOrders: []*common.Order{
705 beforeTradePairs: []*common.TradePair{
707 FromAssetID: assetID1,
712 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
713 delOrders: []*common.Order{
723 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
724 wantOrders: []*common.Order{},
725 wantTradePairs: []*common.TradePair{},
726 wantDBState: &common.MovDatabaseState{Height: 2, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
729 desc: "Add and delete the same trade pair", // Add and delete different transaction pairs
730 beforeOrders: []*common.Order{
740 beforeTradePairs: []*common.TradePair{
742 FromAssetID: assetID1,
747 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
748 addOrders: []*common.Order{
752 delOrders: []*common.Order{
762 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
763 wantOrders: []*common.Order{
767 wantTradePairs: []*common.TradePair{
768 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 2},
770 wantDBState: &common.MovDatabaseState{Height: 2, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
773 desc: "Add and delete different transaction pairs",
774 beforeOrders: []*common.Order{
786 beforeTradePairs: []*common.TradePair{
788 FromAssetID: assetID1,
793 FromAssetID: assetID3,
798 FromAssetID: assetID4,
803 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
804 addOrders: []*common.Order{
809 delOrders: []*common.Order{
820 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
821 wantOrders: []*common.Order{
827 wantTradePairs: []*common.TradePair{
828 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID2, Count: 2},
829 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID2, Count: 1},
830 &common.TradePair{FromAssetID: assetID6, ToAssetID: assetID2, Count: 1},
832 wantDBState: &common.MovDatabaseState{Height: 2, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
836 initBlockHeader := &types.BlockHeader{
841 height := initBlockHeader.Height
842 hash := initBlockHeader.Hash()
844 defer os.RemoveAll("temp")
845 for i, c := range cases {
846 testDB := dbm.NewDB("testdb", "leveldb", "temp")
847 movStore := NewLevelDBMovStore(testDB)
848 if err := movStore.InitDBState(height, &hash); err != nil {
849 t.Fatalf("case %d: InitDBState error %v.", i, err)
852 batch := movStore.db.NewBatch()
853 tradePairsCnt := make(map[string]*common.TradePair)
854 movStore.addOrders(batch, c.beforeOrders, tradePairsCnt)
855 if len(c.beforeOrders) > 0 {
856 tradePairsCnt = make(map[string]*common.TradePair)
857 for _, tradePair := range c.beforeTradePairs {
858 tradePairsCnt[tradePair.Key()] = tradePair
860 movStore.updateTradePairs(batch, tradePairsCnt)
861 movStore.saveMovDatabaseState(batch, c.beforeDBStatus)
865 if err := movStore.ProcessOrders(c.addOrders, c.delOrders, c.blockHeader); err != nil {
866 t.Fatalf("case %d: ProcessOrders error %v.", i, err)
869 var gotOrders []*common.Order
871 tmp, err := movStore.ListOrders(&common.Order{FromAssetID: assetID1, ToAssetID: assetID2, RatioNumerator: 0, RatioDenominator: 1})
873 t.Fatalf("case %d: ListOrders(assetID1 and assetID2) error %v.", i, err)
876 gotOrders = append(gotOrders, tmp...)
878 tmp, err = movStore.ListOrders(&common.Order{FromAssetID: assetID3, ToAssetID: assetID2, RatioNumerator: 0, RatioDenominator: 1})
880 t.Fatalf("case %d: ListOrders(assetID3 and assetID2) error %v.", i, err)
883 gotOrders = append(gotOrders, tmp...)
885 tmp, err = movStore.ListOrders(&common.Order{FromAssetID: assetID4, ToAssetID: assetID2, RatioNumerator: 0, RatioDenominator: 1})
887 t.Fatalf("case %d: ListOrders(assetID4 and assetID2) error %v.", i, err)
890 gotOrders = append(gotOrders, tmp...)
892 tmp, err = movStore.ListOrders(&common.Order{FromAssetID: assetID5, ToAssetID: assetID2, RatioNumerator: 0, RatioDenominator: 1})
894 t.Fatalf("case %d: ListOrders(assetID5 and assetID2) error %v.", i, err)
897 gotOrders = append(gotOrders, tmp...)
899 tmp, err = movStore.ListOrders(&common.Order{FromAssetID: assetID6, ToAssetID: assetID2, RatioNumerator: 0, RatioDenominator: 1})
901 t.Fatalf("case %d: ListOrders(assetID6 and assetID2) error %v.", i, err)
904 gotOrders = append(gotOrders, tmp...)
906 if !testutil.DeepEqual(gotOrders, c.wantOrders) {
907 t.Fatalf("case %d: got orders , gotOrders: %v, wantOrders: %v.", i, gotOrders, c.wantOrders)
910 gotTradePairs, err := movStore.ListTradePairsWithStart(nil, nil)
912 t.Fatalf("case %d: ListTradePairsWithStart error %v.", i, err)
915 if !testutil.DeepEqual(gotTradePairs, c.wantTradePairs) {
916 t.Fatalf("case %d: got tradePairs, gotTradePairs: %v, wantTradePairs: %v.", i, gotTradePairs, c.wantTradePairs)
919 gotDBState, err := movStore.GetMovDatabaseState()
921 t.Fatalf("case %d: GetMovDatabaseState error %v.", i, err)
924 if !testutil.DeepEqual(gotDBState, c.wantDBState) {
925 t.Fatalf("case %d: got tradePairs, gotDBState: %v, wantDBStatus: %v.", i, gotDBState, c.wantDBState)
933 func TestListOrders(t *testing.T) {
936 storeOrders []*common.Order
938 wantOrders []*common.Order
942 query: &common.Order{FromAssetID: assetID1, ToAssetID: assetID2},
943 wantOrders: []*common.Order{},
946 desc: "query from first",
947 storeOrders: []*common.Order{
958 query: &common.Order{FromAssetID: assetID1, ToAssetID: assetID2},
959 wantOrders: []*common.Order{
971 desc: "query from middle",
972 storeOrders: []*common.Order{
982 query: mockOrders[3],
983 wantOrders: []*common.Order{
990 initBlockHeader := &types.BlockHeader{
995 height := initBlockHeader.Height
996 hash := initBlockHeader.Hash()
998 defer os.RemoveAll("temp")
999 for i, c := range cases {
1000 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1001 movStore := NewLevelDBMovStore(testDB)
1002 if err := movStore.InitDBState(height, &hash); err != nil {
1003 t.Fatalf("case %d: InitDBState error %v.", i, err)
1006 batch := movStore.db.NewBatch()
1007 tradePairsCnt := make(map[string]*common.TradePair)
1008 movStore.addOrders(batch, c.storeOrders, tradePairsCnt)
1009 movStore.updateTradePairs(batch, tradePairsCnt)
1012 gotOrders, err := movStore.ListOrders(c.query)
1014 t.Fatalf("case %d: ListOrders error %v.", i, err)
1017 if !testutil.DeepEqual(gotOrders, c.wantOrders) {
1018 t.Fatalf("case %d: got orders , gotOrders: %v, wantOrders: %v.", i, gotOrders, c.wantOrders)
1022 os.RemoveAll("temp")
1026 func TestAddOrders(t *testing.T) {
1029 beforeOrders []*common.Order
1030 addOrders []*common.Order
1031 wantOrders []*common.Order
1035 addOrders: []*common.Order{
1045 wantOrders: []*common.Order{
1057 desc: "Stored data already exists",
1058 beforeOrders: []*common.Order{
1064 addOrders: []*common.Order{
1070 wantOrders: []*common.Order{
1083 initBlockHeader := &types.BlockHeader{
1088 height := initBlockHeader.Height
1089 hash := initBlockHeader.Hash()
1091 defer os.RemoveAll("temp")
1092 for i, c := range cases {
1093 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1094 movStore := NewLevelDBMovStore(testDB)
1095 if err := movStore.InitDBState(height, &hash); err != nil {
1096 t.Fatalf("case %d: InitDBState error %v.", i, err)
1099 batch := movStore.db.NewBatch()
1100 tradePairsCnt := make(map[string]*common.TradePair)
1101 movStore.addOrders(batch, c.beforeOrders, tradePairsCnt)
1102 movStore.updateTradePairs(batch, tradePairsCnt)
1105 tradePairsCnt = make(map[string]*common.TradePair)
1106 movStore.addOrders(batch, c.addOrders, tradePairsCnt)
1109 gotOrders, err := movStore.ListOrders(&common.Order{FromAssetID: assetID1, ToAssetID: assetID2})
1111 t.Fatalf("case %d: ListOrders error %v.", i, err)
1114 if !testutil.DeepEqual(gotOrders, c.wantOrders) {
1115 t.Fatalf("case %d: got orders , gotOrders: %v, wantOrders: %v.", i, gotOrders, c.wantOrders)
1119 os.RemoveAll("temp")
1123 func TestDelOrders(t *testing.T) {
1126 beforeOrders []*common.Order
1127 delOrders []*common.Order
1128 wantOrders []*common.Order
1133 delOrders: []*common.Order{
1137 wantOrders: []*common.Order{},
1138 err: errors.New("don't find trade pair"),
1141 desc: "Delete existing data",
1142 beforeOrders: []*common.Order{
1152 delOrders: []*common.Order{
1158 wantOrders: []*common.Order{
1167 desc: "Delete all data",
1168 beforeOrders: []*common.Order{
1173 delOrders: []*common.Order{
1178 wantOrders: []*common.Order{},
1183 initBlockHeader := &types.BlockHeader{
1188 height := initBlockHeader.Height
1189 hash := initBlockHeader.Hash()
1191 defer os.RemoveAll("temp")
1192 for i, c := range cases {
1193 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1194 movStore := NewLevelDBMovStore(testDB)
1195 if err := movStore.InitDBState(height, &hash); err != nil {
1196 t.Fatalf("case %d: InitDBState error %v.", i, err)
1199 batch := movStore.db.NewBatch()
1200 tradePairsCnt := make(map[string]*common.TradePair)
1201 movStore.addOrders(batch, c.beforeOrders, tradePairsCnt)
1202 movStore.updateTradePairs(batch, tradePairsCnt)
1205 tradePairsCnt = make(map[string]*common.TradePair)
1206 movStore.deleteOrders(batch, c.delOrders, tradePairsCnt)
1207 movStore.updateTradePairs(batch, tradePairsCnt)
1210 gotOrders, err := movStore.ListOrders(&common.Order{FromAssetID: assetID1, ToAssetID: assetID2})
1212 t.Fatalf("case %d: ListOrders error %v.", i, err)
1215 if !testutil.DeepEqual(gotOrders, c.wantOrders) {
1216 t.Fatalf("case %d: got orders , gotOrders: %v, wantOrders: %v.", i, gotOrders, c.wantOrders)
1220 os.RemoveAll("temp")
1224 func TestListTradePairsWithStart(t *testing.T) {
1227 storeTradePairs map[string]*common.TradePair
1228 query *common.TradePair
1229 wantTradePairs []*common.TradePair
1233 query: &common.TradePair{},
1234 wantTradePairs: []*common.TradePair{},
1237 desc: "query from first",
1238 storeTradePairs: map[string]*common.TradePair{
1239 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1240 (&common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3}).Key(): {FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1241 (&common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4}).Key(): {FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1242 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1243 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1244 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1246 query: &common.TradePair{},
1247 wantTradePairs: []*common.TradePair{
1248 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1249 &common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1250 &common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1251 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1252 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1253 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1257 desc: "query from middle",
1258 storeTradePairs: map[string]*common.TradePair{
1259 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1260 (&common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3}).Key(): {FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1261 (&common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4}).Key(): {FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1262 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1263 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1264 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1265 (&common.TradePair{FromAssetID: assetID6, ToAssetID: assetID8}).Key(): {FromAssetID: assetID6, ToAssetID: assetID8, Count: 7},
1267 query: &common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1268 wantTradePairs: []*common.TradePair{
1269 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1270 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1271 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1272 &common.TradePair{FromAssetID: assetID6, ToAssetID: assetID8, Count: 7},
1277 initBlockHeader := &types.BlockHeader{
1282 height := initBlockHeader.Height
1283 hash := initBlockHeader.Hash()
1285 defer os.RemoveAll("temp")
1286 for i, c := range cases {
1287 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1288 movStore := NewLevelDBMovStore(testDB)
1289 if err := movStore.InitDBState(height, &hash); err != nil {
1290 t.Fatalf("case %d: InitDBState error %v.", i, err)
1293 batch := movStore.db.NewBatch()
1294 movStore.updateTradePairs(batch, c.storeTradePairs)
1297 gotTradePairs, err := movStore.ListTradePairsWithStart(c.query.FromAssetID, c.query.ToAssetID)
1299 t.Fatalf("case %d: ListTradePairsWithStart error %v.", i, err)
1302 if !testutil.DeepEqual(gotTradePairs, c.wantTradePairs) {
1303 t.Fatalf("case %d: got TradePairs , gotTradePairs: %v, wantTradePairs: %v.", i, gotTradePairs, c.wantTradePairs)
1307 os.RemoveAll("temp")
1311 func TestUpdateTradePairs(t *testing.T) {
1314 beforeTradePairs map[string]*common.TradePair
1315 addTradePairs map[string]*common.TradePair
1316 delTradePairs map[string]*common.TradePair
1317 wantTradePairs []*common.TradePair
1321 addTradePairs: map[string]*common.TradePair{
1322 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1323 (&common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3}).Key(): {FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1324 (&common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4}).Key(): {FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1325 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1326 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1327 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1329 wantTradePairs: []*common.TradePair{
1330 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1331 &common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1332 &common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1333 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1334 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1335 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1339 desc: "Stored data already exists",
1340 beforeTradePairs: map[string]*common.TradePair{
1341 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1342 (&common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3}).Key(): {FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1343 (&common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4}).Key(): {FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1345 addTradePairs: map[string]*common.TradePair{
1346 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1347 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1348 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1350 wantTradePairs: []*common.TradePair{
1351 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1352 &common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1353 &common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1354 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1355 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1356 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1360 desc: "delete some data",
1361 beforeTradePairs: map[string]*common.TradePair{
1362 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1363 (&common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3}).Key(): {FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1364 (&common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4}).Key(): {FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1365 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1366 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1367 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1369 delTradePairs: map[string]*common.TradePair{
1370 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: -1},
1371 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: -4},
1372 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: -2},
1373 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: -4},
1375 wantTradePairs: []*common.TradePair{
1376 &common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1377 &common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1378 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6, Count: 3},
1379 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7, Count: 2},
1384 initBlockHeader := &types.BlockHeader{
1389 height := initBlockHeader.Height
1390 hash := initBlockHeader.Hash()
1392 defer os.RemoveAll("temp")
1393 for i, c := range cases {
1394 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1395 movStore := NewLevelDBMovStore(testDB)
1396 if err := movStore.InitDBState(height, &hash); err != nil {
1397 t.Fatalf("case %d: InitDBState error %v.", i, err)
1400 batch := movStore.db.NewBatch()
1401 movStore.updateTradePairs(batch, c.beforeTradePairs)
1404 movStore.updateTradePairs(batch, c.addTradePairs)
1405 movStore.updateTradePairs(batch, c.delTradePairs)
1408 gotTradePairs, err := movStore.ListTradePairsWithStart(nil, nil)
1410 t.Fatalf("case %d: ListTradePairsWithStart error %v.", i, err)
1413 if !testutil.DeepEqual(gotTradePairs, c.wantTradePairs) {
1414 t.Fatalf("case %d: got TradePairs , gotTradePairs: %v, wantTradePairs: %v.", i, gotTradePairs, c.wantTradePairs)
1418 os.RemoveAll("temp")
1422 func TestCheckMovDatabaseState(t *testing.T) {
1425 beforeDBStatus *common.MovDatabaseState
1426 blockHeader *types.BlockHeader
1430 desc: "attach Block",
1431 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
1432 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
1436 desc: "error attach Block",
1437 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
1438 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{}},
1439 err: errors.New("the status of the block is inconsistent with that of mov-database"),
1443 desc: "detach Block",
1444 beforeDBStatus: &common.MovDatabaseState{Height: 5, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
1445 blockHeader: &types.BlockHeader{Height: 4},
1449 desc: "error detach Block",
1450 beforeDBStatus: &common.MovDatabaseState{Height: 5, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
1451 blockHeader: &types.BlockHeader{Height: 3},
1452 err: errors.New("the status of the block is inconsistent with that of mov-database"),
1456 initBlockHeader := &types.BlockHeader{
1461 height := initBlockHeader.Height
1462 hash := initBlockHeader.Hash()
1464 defer os.RemoveAll("temp")
1465 for i, c := range cases {
1466 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1467 movStore := NewLevelDBMovStore(testDB)
1468 if err := movStore.InitDBState(height, &hash); err != nil {
1469 t.Fatalf("case %d: InitDBState error %v.", i, err)
1472 batch := movStore.db.NewBatch()
1473 movStore.saveMovDatabaseState(batch, c.beforeDBStatus)
1476 if err := movStore.checkMovDatabaseState(c.blockHeader); c.err != nil && c.err.Error() != err.Error() {
1477 t.Fatalf("case %d: checkMovDatabaseState error %v.", i, err)
1481 os.RemoveAll("temp")