10 "github.com/stretchr/testify/require"
12 "github.com/vapor/application/mov/common"
13 "github.com/vapor/database/leveldb"
14 dbm "github.com/vapor/database/leveldb"
15 "github.com/vapor/protocol/bc"
16 "github.com/vapor/protocol/bc/types"
17 "github.com/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 mockOrders = []*common.Order{
32 FromAssetID: assetID1,
35 Utxo: &common.MovUtxo{
36 SourceID: &bc.Hash{V0: 21},
39 ControlProgram: []byte("aa"),
43 FromAssetID: assetID1,
46 Utxo: &common.MovUtxo{
47 SourceID: &bc.Hash{V0: 22},
50 ControlProgram: []byte("aa"),
54 FromAssetID: assetID1,
57 Utxo: &common.MovUtxo{
58 SourceID: &bc.Hash{V0: 23},
61 ControlProgram: []byte("aa"),
65 FromAssetID: assetID1,
68 Utxo: &common.MovUtxo{
69 SourceID: &bc.Hash{V0: 13},
72 ControlProgram: []byte("aa"),
76 FromAssetID: assetID1,
79 Utxo: &common.MovUtxo{
80 SourceID: &bc.Hash{V0: 24},
83 ControlProgram: []byte("aa"),
87 FromAssetID: assetID1,
90 Utxo: &common.MovUtxo{
91 SourceID: &bc.Hash{V0: 24},
94 ControlProgram: []byte("aa"),
98 FromAssetID: assetID1,
101 Utxo: &common.MovUtxo{
102 SourceID: &bc.Hash{V0: 25},
105 ControlProgram: []byte("aa"),
109 FromAssetID: assetID1,
112 Utxo: &common.MovUtxo{
113 SourceID: &bc.Hash{V0: 26},
116 ControlProgram: []byte("aa"),
120 FromAssetID: assetID1,
123 Utxo: &common.MovUtxo{
124 SourceID: &bc.Hash{V0: 1},
127 ControlProgram: []byte("aa"),
131 FromAssetID: assetID1,
134 Utxo: &common.MovUtxo{
135 SourceID: &bc.Hash{V0: 2},
138 ControlProgram: []byte("aa"),
142 FromAssetID: assetID3,
145 Utxo: &common.MovUtxo{
146 SourceID: &bc.Hash{V0: 33},
149 ControlProgram: []byte("aa"),
153 FromAssetID: assetID4,
156 Utxo: &common.MovUtxo{
157 SourceID: &bc.Hash{V0: 34},
160 ControlProgram: []byte("aa"),
164 FromAssetID: assetID4,
167 Utxo: &common.MovUtxo{
168 SourceID: &bc.Hash{V0: 36},
171 ControlProgram: []byte("aa"),
175 FromAssetID: assetID5,
178 Utxo: &common.MovUtxo{
179 SourceID: &bc.Hash{V0: 37},
182 ControlProgram: []byte("aa"),
186 FromAssetID: assetID6,
189 Utxo: &common.MovUtxo{
190 SourceID: &bc.Hash{V0: 38},
193 ControlProgram: []byte("aa"),
199 func TestGetAssetIDFromTradePairKey(t *testing.T) {
200 b := calcTradePairKey(assetID1, assetID2)
201 gotA := getAssetIDFromTradePairKey(b, fromAssetIDPos)
202 gotB := getAssetIDFromTradePairKey(b, toAssetIDPos)
204 if *gotA != *assetID1 {
205 t.Fatalf("got wrong from asset id got %s, want %s", gotA.String(), assetID1.String())
208 if *gotB != *assetID2 {
209 t.Fatalf("got wrong to asset id got %s, want %s", gotB.String(), assetID2.String())
213 func TestSortOrderKey(t *testing.T) {
214 dirname, err := ioutil.TempDir("", "db_common_test")
217 db, err := leveldb.NewGoLevelDB("testdb", dirname)
224 os.RemoveAll(dirname)
227 type expectedData struct {
233 orders []*common.Order
237 orders: []*common.Order{
239 FromAssetID: &bc.AssetID{V0: 1},
240 ToAssetID: &bc.AssetID{V0: 0},
242 Utxo: &common.MovUtxo{
243 SourceID: &bc.Hash{V0: 21},
246 ControlProgram: []byte("aa"),
250 FromAssetID: &bc.AssetID{V0: 1},
251 ToAssetID: &bc.AssetID{V0: 0},
253 Utxo: &common.MovUtxo{
254 SourceID: &bc.Hash{V0: 22},
257 ControlProgram: []byte("aa"),
261 FromAssetID: &bc.AssetID{V0: 1},
262 ToAssetID: &bc.AssetID{V0: 0},
264 Utxo: &common.MovUtxo{
265 SourceID: &bc.Hash{V0: 23},
268 ControlProgram: []byte("aa"),
272 FromAssetID: &bc.AssetID{V0: 1},
273 ToAssetID: &bc.AssetID{V0: 0},
275 Utxo: &common.MovUtxo{
276 SourceID: &bc.Hash{V0: 13},
279 ControlProgram: []byte("aa"),
283 FromAssetID: &bc.AssetID{V0: 1},
284 ToAssetID: &bc.AssetID{V0: 0},
286 Utxo: &common.MovUtxo{
287 SourceID: &bc.Hash{V0: 24},
290 ControlProgram: []byte("aa"),
294 FromAssetID: &bc.AssetID{V0: 1},
295 ToAssetID: &bc.AssetID{V0: 0},
297 Utxo: &common.MovUtxo{
298 SourceID: &bc.Hash{V0: 25},
301 ControlProgram: []byte("aa"),
305 FromAssetID: &bc.AssetID{V0: 1},
306 ToAssetID: &bc.AssetID{V0: 0},
308 Utxo: &common.MovUtxo{
309 SourceID: &bc.Hash{V0: 26},
312 ControlProgram: []byte("aa"),
316 FromAssetID: &bc.AssetID{V0: 1},
317 ToAssetID: &bc.AssetID{V0: 0},
319 Utxo: &common.MovUtxo{
320 SourceID: &bc.Hash{V0: 27},
323 ControlProgram: []byte("aa"),
327 FromAssetID: &bc.AssetID{V0: 1},
328 ToAssetID: &bc.AssetID{V0: 0},
330 Utxo: &common.MovUtxo{
331 SourceID: &bc.Hash{V0: 24},
334 ControlProgram: []byte("aa"),
338 FromAssetID: &bc.AssetID{V0: 1},
339 ToAssetID: &bc.AssetID{V0: 0},
341 Utxo: &common.MovUtxo{
342 SourceID: &bc.Hash{V0: 25},
345 ControlProgram: []byte("aa"),
349 FromAssetID: &bc.AssetID{V0: 1},
350 ToAssetID: &bc.AssetID{V0: 0},
352 Utxo: &common.MovUtxo{
353 SourceID: &bc.Hash{V0: 26},
356 ControlProgram: []byte("aa"),
360 FromAssetID: &bc.AssetID{V0: 1},
361 ToAssetID: &bc.AssetID{V0: 0},
363 Utxo: &common.MovUtxo{
364 SourceID: &bc.Hash{V0: 26},
367 ControlProgram: []byte("aa"),
371 FromAssetID: &bc.AssetID{V0: 1},
372 ToAssetID: &bc.AssetID{V0: 0},
374 Utxo: &common.MovUtxo{
375 SourceID: &bc.Hash{V0: 27},
378 ControlProgram: []byte("aa"),
382 FromAssetID: &bc.AssetID{V0: 1},
383 ToAssetID: &bc.AssetID{V0: 0},
385 Utxo: &common.MovUtxo{
386 SourceID: &bc.Hash{V0: 28},
389 ControlProgram: []byte("aa"),
393 FromAssetID: &bc.AssetID{V0: 1},
394 ToAssetID: &bc.AssetID{V0: 0},
396 Utxo: &common.MovUtxo{
397 SourceID: &bc.Hash{V0: 29},
400 ControlProgram: []byte("aa"),
404 FromAssetID: &bc.AssetID{V0: 1},
405 ToAssetID: &bc.AssetID{V0: 0},
407 Utxo: &common.MovUtxo{
408 SourceID: &bc.Hash{V0: 30},
411 ControlProgram: []byte("aa"),
415 FromAssetID: &bc.AssetID{V0: 1},
416 ToAssetID: &bc.AssetID{V0: 0},
418 Utxo: &common.MovUtxo{
419 SourceID: &bc.Hash{V0: 31},
422 ControlProgram: []byte("aa"),
426 FromAssetID: &bc.AssetID{V0: 1},
427 ToAssetID: &bc.AssetID{V0: 0},
429 Utxo: &common.MovUtxo{
430 SourceID: &bc.Hash{V0: 32},
433 ControlProgram: []byte("aa"),
437 FromAssetID: &bc.AssetID{V0: 1},
438 ToAssetID: &bc.AssetID{V0: 0},
440 Utxo: &common.MovUtxo{
441 SourceID: &bc.Hash{V0: 33},
444 ControlProgram: []byte("aa"),
448 want: []expectedData{
451 utxoHash: "f1b85307cf1f4eb6b193b6fc289413fdbb12bc362ced399762589b016e54dd02",
455 utxoHash: "49ef60af0f24962ed129a73142048ed0cb589041c629353932e3c3e0a4e822ba",
459 utxoHash: "67b2ac6ea71b271e72836e162811866f291ed2fab106c43519ca0c94ef8a5dce",
463 utxoHash: "47ff45b7b530512142981c2cee82faad63d6c9e7ffed0e72c3e42668f13b296f",
467 utxoHash: "b750d0b95f38043362c8335f242f97cfd3e1cada8fd171b914471a16cc0f14c6",
471 utxoHash: "04386ef57f0ca1be0a9be46c413900adbc0ab1e90e773959924aa73ca62edf64",
475 utxoHash: "c0fe6227c50da350a5e7b4ff85c18e9c901c323521067b9142acd128cf13ae82",
479 utxoHash: "47ff45b7b530512142981c2cee82faad63d6c9e7ffed0e72c3e42668f13b296f",
483 utxoHash: "bc92df1cbd20c98b0d18c9d93422a770849235867522a08e492196d16ed0a422",
487 utxoHash: "0cc0ded6fb337a3c5e6e4d008d6167dc58bdede43713898e914d65cda3b8499a",
491 utxoHash: "14b51a6103f75d9cacdf0f9551467588c687ed3b029e25c646d276720569e227",
495 utxoHash: "1fa9fae83d0a5401a4e92f80636966486e763eecca588aa11dff02b415320602",
499 utxoHash: "6687d18ddbe4e7381a844e393ca3032a412285c9da6988eff182106e28ba09ca",
503 utxoHash: "841b1de7c871dfe6e2d1886809d9ae12ec45e570233b03879305232b096fda43",
507 utxoHash: "a4bc534c267d35a9eafc25cd66e0cb270a2537a51186605b7f7591bc567ab4c6",
511 utxoHash: "fdedf4117def659e07cc8a8ca318d21ae577a05e1a0197844b54d493bdae5854",
515 utxoHash: "20be3bd2d406bb7fe6627b32768fb2073e997b962a4badfa4384210fed2ab9c6",
519 utxoHash: "72192f56b9525c74c6a9f0419563bc0da76b0f3d6e89d9decdb6e67786ac3909",
523 utxoHash: "7886844334659b4feffc41528cf81192925d3aa4a5ccb3652200b9073b7d47c3",
529 for i, c := range cases {
530 for _, order := range c.orders {
531 key := calcOrderKey(order.FromAssetID, order.ToAssetID, order.UTXOHash(), order.Rate)
532 data, err := json.Marshal(order.Utxo)
537 db.SetSync(key, data)
540 got := []expectedData{}
541 itr := db.IteratorPrefixWithStart(nil, nil, false)
544 pos := len(ordersPrefix) + assetIDLen*2
546 copy(b[:], key[pos+8:])
547 utxoHash := bc.NewHash(b)
549 got = append(got, expectedData{
550 rate: getRateFromOrderKey(key),
551 utxoHash: utxoHash.String(),
556 if !testutil.DeepEqual(c.want, got) {
557 t.Errorf("case %v: got recovery status, got: %v, want: %v.", i, got, c.want)
562 func TestMovStore(t *testing.T) {
565 beforeOrders []*common.Order
566 beforeTradePairs []*common.TradePair
567 beforeDBStatus *common.MovDatabaseState
568 addOrders []*common.Order
569 delOrders []*common.Order
570 blockHeader *types.BlockHeader
571 wantOrders []*common.Order
572 wantTradePairs []*common.TradePair
573 wantDBState *common.MovDatabaseState
577 addOrders: []*common.Order{
587 blockHeader: &types.BlockHeader{Height: 1, PreviousBlockHash: bc.Hash{V0: 524821139490765641, V1: 2484214155808702787, V2: 9108473449351508820, V3: 7972721253564512122}},
588 wantOrders: []*common.Order{
598 wantTradePairs: []*common.TradePair{
599 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 8},
601 wantDBState: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
604 desc: "del some order",
605 beforeOrders: []*common.Order{
615 beforeTradePairs: []*common.TradePair{
617 FromAssetID: assetID1,
622 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
623 delOrders: []*common.Order{
628 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
629 wantOrders: []*common.Order{
636 wantTradePairs: []*common.TradePair{
637 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 5},
639 wantDBState: &common.MovDatabaseState{Height: 2, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
642 desc: "del all order",
643 beforeOrders: []*common.Order{
653 beforeTradePairs: []*common.TradePair{
655 FromAssetID: assetID1,
660 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
661 delOrders: []*common.Order{
671 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
672 wantOrders: []*common.Order{},
673 wantTradePairs: []*common.TradePair{},
674 wantDBState: &common.MovDatabaseState{Height: 2, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
677 desc: "Add and delete the same trade pair", //Add and delete different transaction pairs
678 beforeOrders: []*common.Order{
688 beforeTradePairs: []*common.TradePair{
690 FromAssetID: assetID1,
695 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
696 addOrders: []*common.Order{
700 delOrders: []*common.Order{
710 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
711 wantOrders: []*common.Order{
715 wantTradePairs: []*common.TradePair{
716 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 2},
718 wantDBState: &common.MovDatabaseState{Height: 2, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
721 desc: "Add and delete different transaction pairs",
722 beforeOrders: []*common.Order{
734 beforeTradePairs: []*common.TradePair{
736 FromAssetID: assetID1,
741 FromAssetID: assetID3,
746 FromAssetID: assetID4,
751 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
752 addOrders: []*common.Order{
757 delOrders: []*common.Order{
768 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
769 wantOrders: []*common.Order{
775 wantTradePairs: []*common.TradePair{
776 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID2, Count: 2},
777 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID2, Count: 1},
778 &common.TradePair{FromAssetID: assetID6, ToAssetID: assetID2, Count: 1},
780 wantDBState: &common.MovDatabaseState{Height: 2, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
784 initBlockHeader := &types.BlockHeader{
789 height := initBlockHeader.Height
790 hash := initBlockHeader.Hash()
792 defer os.RemoveAll("temp")
793 for i, c := range cases {
794 testDB := dbm.NewDB("testdb", "leveldb", "temp")
795 movStore := NewLevelDBMovStore(testDB)
796 if err := movStore.InitDBState(height, &hash); err != nil {
797 t.Fatalf("case %d: InitDBState error %v.", i, err)
800 batch := movStore.db.NewBatch()
801 tradePairsCnt := make(map[string]*common.TradePair)
802 movStore.addOrders(batch, c.beforeOrders, tradePairsCnt)
803 if len(c.beforeOrders) > 0 {
804 tradePairsCnt = make(map[string]*common.TradePair)
805 for _, tradePair := range c.beforeTradePairs {
806 tradePairsCnt[tradePair.Key()] = tradePair
808 movStore.updateTradePairs(batch, tradePairsCnt)
809 movStore.saveMovDatabaseState(batch, c.beforeDBStatus)
813 if err := movStore.ProcessOrders(c.addOrders, c.delOrders, c.blockHeader); err != nil {
814 t.Fatalf("case %d: ProcessOrders error %v.", i, err)
817 var gotOrders []*common.Order
819 tmp, err := movStore.ListOrders(&common.Order{FromAssetID: assetID1, ToAssetID: assetID2, Rate: 0})
821 t.Fatalf("case %d: ListOrders(assetID1 and assetID2) error %v.", i, err)
824 gotOrders = append(gotOrders, tmp...)
826 tmp, err = movStore.ListOrders(&common.Order{FromAssetID: assetID3, ToAssetID: assetID2, Rate: 0})
828 t.Fatalf("case %d: ListOrders(assetID3 and assetID2) error %v.", i, err)
831 gotOrders = append(gotOrders, tmp...)
833 tmp, err = movStore.ListOrders(&common.Order{FromAssetID: assetID4, ToAssetID: assetID2, Rate: 0})
835 t.Fatalf("case %d: ListOrders(assetID4 and assetID2) error %v.", i, err)
838 gotOrders = append(gotOrders, tmp...)
840 tmp, err = movStore.ListOrders(&common.Order{FromAssetID: assetID5, ToAssetID: assetID2, Rate: 0})
842 t.Fatalf("case %d: ListOrders(assetID5 and assetID2) error %v.", i, err)
845 gotOrders = append(gotOrders, tmp...)
847 tmp, err = movStore.ListOrders(&common.Order{FromAssetID: assetID6, ToAssetID: assetID2, Rate: 0})
849 t.Fatalf("case %d: ListOrders(assetID6 and assetID2) error %v.", i, err)
852 gotOrders = append(gotOrders, tmp...)
854 if !testutil.DeepEqual(gotOrders, c.wantOrders) {
855 t.Fatalf("case %d: got orders , gotOrders: %v, wantOrders: %v.", i, gotOrders, c.wantOrders)
858 gotTradePairs, err := movStore.ListTradePairsWithStart(nil, nil)
860 t.Fatalf("case %d: ListTradePairsWithStart error %v.", i, err)
863 if !testutil.DeepEqual(gotTradePairs, c.wantTradePairs) {
864 t.Fatalf("case %d: got tradePairs, gotTradePairs: %v, wantTradePairs: %v.", i, gotTradePairs, c.wantTradePairs)
867 gotDBState, err := movStore.GetMovDatabaseState()
869 t.Fatalf("case %d: GetMovDatabaseState error %v.", i, err)
872 if !testutil.DeepEqual(gotDBState, c.wantDBState) {
873 t.Fatalf("case %d: got tradePairs, gotDBState: %v, wantDBStatus: %v.", i, gotDBState, c.wantDBState)
881 func TestListOrders(t *testing.T) {
884 storeOrders []*common.Order
886 wantOrders []*common.Order
890 query: &common.Order{FromAssetID: assetID1, ToAssetID: assetID2},
891 wantOrders: []*common.Order{},
894 desc: "query from first",
895 storeOrders: []*common.Order{
906 query: &common.Order{FromAssetID: assetID1, ToAssetID: assetID2},
907 wantOrders: []*common.Order{
919 desc: "query from middle",
920 storeOrders: []*common.Order{
930 query: mockOrders[3],
931 wantOrders: []*common.Order{
939 initBlockHeader := &types.BlockHeader{
944 height := initBlockHeader.Height
945 hash := initBlockHeader.Hash()
947 defer os.RemoveAll("temp")
948 for i, c := range cases {
949 testDB := dbm.NewDB("testdb", "leveldb", "temp")
950 movStore := NewLevelDBMovStore(testDB)
951 if err := movStore.InitDBState(height, &hash); err != nil {
952 t.Fatalf("case %d: InitDBState error %v.", i, err)
955 batch := movStore.db.NewBatch()
956 tradePairsCnt := make(map[string]*common.TradePair)
957 movStore.addOrders(batch, c.storeOrders, tradePairsCnt)
958 movStore.updateTradePairs(batch, tradePairsCnt)
961 gotOrders, err := movStore.ListOrders(c.query)
963 t.Fatalf("case %d: ListOrders error %v.", i, err)
966 if !testutil.DeepEqual(gotOrders, c.wantOrders) {
967 t.Fatalf("case %d: got orders , gotOrders: %v, wantOrders: %v.", i, gotOrders, c.wantOrders)
975 func TestAddOrders(t *testing.T) {
978 beforeOrders []*common.Order
979 addOrders []*common.Order
980 wantOrders []*common.Order
984 addOrders: []*common.Order{
994 wantOrders: []*common.Order{
1006 desc: "Stored data already exists",
1007 beforeOrders: []*common.Order{
1013 addOrders: []*common.Order{
1019 wantOrders: []*common.Order{
1032 initBlockHeader := &types.BlockHeader{
1037 height := initBlockHeader.Height
1038 hash := initBlockHeader.Hash()
1040 defer os.RemoveAll("temp")
1041 for i, c := range cases {
1042 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1043 movStore := NewLevelDBMovStore(testDB)
1044 if err := movStore.InitDBState(height, &hash); err != nil {
1045 t.Fatalf("case %d: InitDBState error %v.", i, err)
1048 batch := movStore.db.NewBatch()
1049 tradePairsCnt := make(map[string]*common.TradePair)
1050 movStore.addOrders(batch, c.beforeOrders, tradePairsCnt)
1051 movStore.updateTradePairs(batch, tradePairsCnt)
1054 tradePairsCnt = make(map[string]*common.TradePair)
1055 movStore.addOrders(batch, c.addOrders, tradePairsCnt)
1058 gotOrders, err := movStore.ListOrders(&common.Order{FromAssetID: assetID1, ToAssetID: assetID2})
1060 t.Fatalf("case %d: ListOrders error %v.", i, err)
1063 if !testutil.DeepEqual(gotOrders, c.wantOrders) {
1064 t.Fatalf("case %d: got orders , gotOrders: %v, wantOrders: %v.", i, gotOrders, c.wantOrders)
1068 os.RemoveAll("temp")
1072 func TestDelOrders(t *testing.T) {
1075 beforeOrders []*common.Order
1076 delOrders []*common.Order
1077 wantOrders []*common.Order
1082 delOrders: []*common.Order{
1086 wantOrders: []*common.Order{},
1087 err: errors.New("don't find trade pair"),
1090 desc: "Delete existing data",
1091 beforeOrders: []*common.Order{
1101 delOrders: []*common.Order{
1107 wantOrders: []*common.Order{
1116 desc: "Delete all data",
1117 beforeOrders: []*common.Order{
1122 delOrders: []*common.Order{
1127 wantOrders: []*common.Order{},
1132 initBlockHeader := &types.BlockHeader{
1137 height := initBlockHeader.Height
1138 hash := initBlockHeader.Hash()
1140 defer os.RemoveAll("temp")
1141 for i, c := range cases {
1142 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1143 movStore := NewLevelDBMovStore(testDB)
1144 if err := movStore.InitDBState(height, &hash); err != nil {
1145 t.Fatalf("case %d: InitDBState error %v.", i, err)
1148 batch := movStore.db.NewBatch()
1149 tradePairsCnt := make(map[string]*common.TradePair)
1150 movStore.addOrders(batch, c.beforeOrders, tradePairsCnt)
1151 movStore.updateTradePairs(batch, tradePairsCnt)
1154 tradePairsCnt = make(map[string]*common.TradePair)
1155 movStore.deleteOrders(batch, c.delOrders, tradePairsCnt)
1156 movStore.updateTradePairs(batch, tradePairsCnt)
1159 gotOrders, err := movStore.ListOrders(&common.Order{FromAssetID: assetID1, ToAssetID: assetID2})
1161 t.Fatalf("case %d: ListOrders error %v.", i, err)
1164 if !testutil.DeepEqual(gotOrders, c.wantOrders) {
1165 t.Fatalf("case %d: got orders , gotOrders: %v, wantOrders: %v.", i, gotOrders, c.wantOrders)
1169 os.RemoveAll("temp")
1173 func TestListTradePairsWithStart(t *testing.T) {
1176 storeTradePairs map[string]*common.TradePair
1177 query *common.TradePair
1178 wantTradePairs []*common.TradePair
1182 query: &common.TradePair{},
1183 wantTradePairs: []*common.TradePair{},
1186 desc: "query from first",
1187 storeTradePairs: map[string]*common.TradePair{
1188 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1189 (&common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3}).Key(): {FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1190 (&common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4}).Key(): {FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1191 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1192 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1193 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1195 query: &common.TradePair{},
1196 wantTradePairs: []*common.TradePair{
1197 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1198 &common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1199 &common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1200 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1201 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1202 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1206 desc: "query from middle",
1207 storeTradePairs: map[string]*common.TradePair{
1208 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1209 (&common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3}).Key(): {FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1210 (&common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4}).Key(): {FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1211 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1212 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1213 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1214 (&common.TradePair{FromAssetID: assetID6, ToAssetID: assetID8}).Key(): {FromAssetID: assetID6, ToAssetID: assetID8, Count: 7},
1216 query: &common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1217 wantTradePairs: []*common.TradePair{
1218 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1219 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1220 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1221 &common.TradePair{FromAssetID: assetID6, ToAssetID: assetID8, Count: 7},
1226 initBlockHeader := &types.BlockHeader{
1231 height := initBlockHeader.Height
1232 hash := initBlockHeader.Hash()
1234 defer os.RemoveAll("temp")
1235 for i, c := range cases {
1236 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1237 movStore := NewLevelDBMovStore(testDB)
1238 if err := movStore.InitDBState(height, &hash); err != nil {
1239 t.Fatalf("case %d: InitDBState error %v.", i, err)
1242 batch := movStore.db.NewBatch()
1243 movStore.updateTradePairs(batch, c.storeTradePairs)
1246 gotTradePairs, err := movStore.ListTradePairsWithStart(c.query.FromAssetID, c.query.ToAssetID)
1248 t.Fatalf("case %d: ListTradePairsWithStart error %v.", i, err)
1251 if !testutil.DeepEqual(gotTradePairs, c.wantTradePairs) {
1252 t.Fatalf("case %d: got TradePairs , gotTradePairs: %v, wantTradePairs: %v.", i, gotTradePairs, c.wantTradePairs)
1256 os.RemoveAll("temp")
1260 func TestUpdateTradePairs(t *testing.T) {
1263 beforeTradePairs map[string]*common.TradePair
1264 addTradePairs map[string]*common.TradePair
1265 delTradePairs map[string]*common.TradePair
1266 wantTradePairs []*common.TradePair
1270 addTradePairs: map[string]*common.TradePair{
1271 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1272 (&common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3}).Key(): {FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1273 (&common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4}).Key(): {FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1274 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1275 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1276 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1278 wantTradePairs: []*common.TradePair{
1279 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1280 &common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1281 &common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1282 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1283 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1284 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1288 desc: "Stored data already exists",
1289 beforeTradePairs: map[string]*common.TradePair{
1290 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1291 (&common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3}).Key(): {FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1292 (&common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4}).Key(): {FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1294 addTradePairs: map[string]*common.TradePair{
1295 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1296 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1297 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1299 wantTradePairs: []*common.TradePair{
1300 &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1301 &common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1302 &common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1303 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1304 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1305 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1309 desc: "delete some data",
1310 beforeTradePairs: map[string]*common.TradePair{
1311 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: 1},
1312 (&common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3}).Key(): {FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1313 (&common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4}).Key(): {FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1314 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: 4},
1315 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: 5},
1316 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: 6},
1318 delTradePairs: map[string]*common.TradePair{
1319 (&common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2}).Key(): {FromAssetID: assetID1, ToAssetID: assetID2, Count: -1},
1320 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID5}).Key(): {FromAssetID: assetID4, ToAssetID: assetID5, Count: -4},
1321 (&common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6}).Key(): {FromAssetID: assetID4, ToAssetID: assetID6, Count: -2},
1322 (&common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7}).Key(): {FromAssetID: assetID5, ToAssetID: assetID7, Count: -4},
1324 wantTradePairs: []*common.TradePair{
1325 &common.TradePair{FromAssetID: assetID2, ToAssetID: assetID3, Count: 2},
1326 &common.TradePair{FromAssetID: assetID3, ToAssetID: assetID4, Count: 3},
1327 &common.TradePair{FromAssetID: assetID4, ToAssetID: assetID6, Count: 3},
1328 &common.TradePair{FromAssetID: assetID5, ToAssetID: assetID7, Count: 2},
1333 initBlockHeader := &types.BlockHeader{
1338 height := initBlockHeader.Height
1339 hash := initBlockHeader.Hash()
1341 defer os.RemoveAll("temp")
1342 for i, c := range cases {
1343 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1344 movStore := NewLevelDBMovStore(testDB)
1345 if err := movStore.InitDBState(height, &hash); err != nil {
1346 t.Fatalf("case %d: InitDBState error %v.", i, err)
1349 batch := movStore.db.NewBatch()
1350 movStore.updateTradePairs(batch, c.beforeTradePairs)
1353 movStore.updateTradePairs(batch, c.addTradePairs)
1354 movStore.updateTradePairs(batch, c.delTradePairs)
1357 gotTradePairs, err := movStore.ListTradePairsWithStart(nil, nil)
1359 t.Fatalf("case %d: ListTradePairsWithStart error %v.", i, err)
1362 if !testutil.DeepEqual(gotTradePairs, c.wantTradePairs) {
1363 t.Fatalf("case %d: got TradePairs , gotTradePairs: %v, wantTradePairs: %v.", i, gotTradePairs, c.wantTradePairs)
1367 os.RemoveAll("temp")
1371 func TestCheckMovDatabaseState(t *testing.T) {
1374 beforeDBStatus *common.MovDatabaseState
1375 blockHeader *types.BlockHeader
1379 desc: "attach Block",
1380 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
1381 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
1385 desc: "error attach Block",
1386 beforeDBStatus: &common.MovDatabaseState{Height: 1, Hash: &bc.Hash{V0: 14213576368347360351, V1: 16287398171800437029, V2: 9513543230620030445, V3: 8534035697182508177}},
1387 blockHeader: &types.BlockHeader{Height: 2, PreviousBlockHash: bc.Hash{}},
1388 err: errors.New("the status of the block is inconsistent with that of mov-database"),
1392 desc: "detach Block",
1393 beforeDBStatus: &common.MovDatabaseState{Height: 5, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
1394 blockHeader: &types.BlockHeader{Height: 4},
1398 desc: "error detach Block",
1399 beforeDBStatus: &common.MovDatabaseState{Height: 5, Hash: &bc.Hash{V0: 3724755213446347384, V1: 158878632373345042, V2: 18283800951484248781, V3: 7520797730449067221}},
1400 blockHeader: &types.BlockHeader{Height: 3},
1401 err: errors.New("the status of the block is inconsistent with that of mov-database"),
1405 initBlockHeader := &types.BlockHeader{
1410 height := initBlockHeader.Height
1411 hash := initBlockHeader.Hash()
1413 defer os.RemoveAll("temp")
1414 for i, c := range cases {
1415 testDB := dbm.NewDB("testdb", "leveldb", "temp")
1416 movStore := NewLevelDBMovStore(testDB)
1417 if err := movStore.InitDBState(height, &hash); err != nil {
1418 t.Fatalf("case %d: InitDBState error %v.", i, err)
1421 batch := movStore.db.NewBatch()
1422 movStore.saveMovDatabaseState(batch, c.beforeDBStatus)
1425 if err := movStore.checkMovDatabaseState(c.blockHeader); c.err != nil && c.err.Error() != err.Error() {
1426 t.Fatalf("case %d: checkMovDatabaseState error %v.", i, err)
1430 os.RemoveAll("temp")