From 3f89eeb07b7d9d8e8657487e1d6ec49e6f53e2d1 Mon Sep 17 00:00:00 2001 From: wz Date: Wed, 25 Sep 2019 10:23:28 +0800 Subject: [PATCH] database struct (#401) * database struct * modify filename * modify dir * fix rebiew * fix * add error for return * fix * fix --- application/dex/common/type.go | 28 +++ application/dex/database/dex_store.go | 78 +++++++ application/dex/database/dex_store_test.go | 323 +++++++++++++++++++++++++++++ 3 files changed, 429 insertions(+) create mode 100644 application/dex/common/type.go create mode 100644 application/dex/database/dex_store.go create mode 100644 application/dex/database/dex_store_test.go diff --git a/application/dex/common/type.go b/application/dex/common/type.go new file mode 100644 index 00000000..63baf2b8 --- /dev/null +++ b/application/dex/common/type.go @@ -0,0 +1,28 @@ +package common + +import "github.com/vapor/protocol/bc" + +type DexUtxo struct { + SourceID *bc.Hash + SourcePos uint64 + Amount uint64 + ControlProgram []byte +} + +type Order struct { + FromAssetID *bc.AssetID + ToAssetID *bc.AssetID + Utxo *DexUtxo + Rate float64 +} + +type TradePair struct { + FromAssetID *bc.AssetID + ToAssetID *bc.AssetID + Count uint64 +} + +type DexDatabaseState struct { + Height uint64 + Hash *bc.Hash +} diff --git a/application/dex/database/dex_store.go b/application/dex/database/dex_store.go new file mode 100644 index 00000000..9035ac01 --- /dev/null +++ b/application/dex/database/dex_store.go @@ -0,0 +1,78 @@ +package database + +import ( + "encoding/binary" + "math" + + "github.com/vapor/application/dex/common" + dbm "github.com/vapor/database/leveldb" + "github.com/vapor/protocol/bc" +) + +const ( + order byte = iota + tradePair + matchStatus +) + +var ( + dexStore = []byte("DEX:") + ordersPreFix = append(dexStore, order) + tradePairPreFix = append(dexStore, tradePair) + bestMatchStore = append(dexStore, matchStatus) +) + +func calcOrdersPrefix(fromAssetID, toAssetID *bc.AssetID, utxoHash *bc.Hash, rate float64) []byte { + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, math.Float64bits(rate)) + key := append(ordersPreFix, fromAssetID.Bytes()...) + key = append(key, toAssetID.Bytes()...) + key = append(key, buf...) + return append(key, utxoHash.Bytes()...) +} + +func calcTradePairPreFix(fromAssetID, toAssetID *bc.Hash) []byte { + key := append(ordersPreFix, fromAssetID.Bytes()...) + return append(key, toAssetID.Bytes()...) +} + +type DexTradeOrderDB struct { + db dbm.DB +} + +func (d *DexTradeOrderDB) GetTradePairsWithStart(start []byte) ([]common.TradePair, error) { + return nil, nil +} + +func (d *DexTradeOrderDB) addTradePair() error { + return nil +} + +func (d *DexTradeOrderDB) deleteTradePair() error { + return nil +} + +func (d *DexTradeOrderDB) ProcessOrders(addOrders []*common.Order, delOreders []*common.Order, height uint64, blockHash *bc.Hash) error { + + return nil +} + +func (d *DexTradeOrderDB) addOrders(orders []*common.Order) error { + return nil +} + +func (d *DexTradeOrderDB) deleteOrder(orders []*common.Order) error { + return nil +} + +func (d *DexTradeOrderDB) ListOrders(fromAssetID, toAssetID string, rateAfter float64) ([]*common.Order, error) { + return nil, nil +} + +func (d *DexTradeOrderDB) GetDexDatabaseState() (*common.DexDatabaseState, error) { + return nil, nil +} + +func (d *DexTradeOrderDB) saveDexDatabaseState(state *common.DexDatabaseState) error { + return nil +} diff --git a/application/dex/database/dex_store_test.go b/application/dex/database/dex_store_test.go new file mode 100644 index 00000000..c72e6322 --- /dev/null +++ b/application/dex/database/dex_store_test.go @@ -0,0 +1,323 @@ +package database + +import ( + "encoding/binary" + "encoding/json" + "io/ioutil" + "math" + "os" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" + + "github.com/vapor/application/dex/common" + "github.com/vapor/database/leveldb" + "github.com/vapor/protocol/bc" + "github.com/vapor/testutil" +) + +func TestSortOrderKey(t *testing.T) { + dirname, err := ioutil.TempDir("", "db_common_test") + require.Nil(t, err) + + db, err := leveldb.NewGoLevelDB("testdb", dirname) + if err != nil { + t.Fatal(err) + } + + defer func() { + db.Close() + os.RemoveAll(dirname) + }() + + type expectedData struct { + rate float64 + utxoHash string + } + + cases := []struct { + orders []common.Order + want []expectedData + }{ + { + orders: []common.Order{ + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 1.00090, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 21}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00090, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 22}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00097, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 23}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00098, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 13}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00098, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 24}, + Amount: 10, + SourcePos: 1, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00099, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 24}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00096, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 25}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00095, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 26}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00091, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 26}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00092, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 27}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00093, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 28}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00094, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 29}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00077, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 30}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 0.00088, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 31}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 999999.9521, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 32}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + common.Order{ + FromAssetID: &bc.AssetID{V0: 1}, + ToAssetID: &bc.AssetID{V0: 0}, + Rate: 888888.7954, + Utxo: &common.DexUtxo{ + SourceID: &bc.Hash{V0: 33}, + Amount: 1, + SourcePos: 0, + ControlProgram: []byte("aa"), + }, + }, + }, + want: []expectedData{ + expectedData{ + rate: 0.00077, + utxoHash: "7967bb8c4cca951749553e9c7787255d35a032d9e1acecefe4011c8095dc8e6f", + }, + expectedData{ + rate: 0.00088, + utxoHash: "215a6e7e3a5006151bd0b81c54fcccda0381f3a22e7b6646ed201c35f9fa6c5a", + }, + expectedData{ + rate: 0.00090, + utxoHash: "cb373d3a383d30eb2863317ea2cfb5b4b269772fbc0fb8413a2be7d7b69ec2b9", + }, + expectedData{ + rate: 0.00091, + utxoHash: "298c39d327cb4b0dcefcf701aa8d1b559f1de0148e9bcbe14da48cfa268c01ea", + }, + expectedData{ + rate: 0.00092, + utxoHash: "b2c59190fb0d948c9545c146a69b1f17503b2d280b2f3f45ecc0a7b7e2cd1784", + }, + expectedData{ + rate: 0.00093, + utxoHash: "80b44aae2b2cf57bd2cf77cb88f0d8363066f5f16a17a3e85224ecbbc6387d8b", + }, + expectedData{ + rate: 0.00094, + utxoHash: "4843adc8c4a50672a022e5f377dfd2ac11119364dc0a547be45b4a5edacef33b", + }, + expectedData{ + rate: 0.00095, + utxoHash: "298c39d327cb4b0dcefcf701aa8d1b559f1de0148e9bcbe14da48cfa268c01ea", + }, + expectedData{ + rate: 0.00096, + utxoHash: "d8d1a85303e9ac738e675b874b866e5ffbfa10e05201113404dde544055a18b9", + }, + expectedData{ + rate: 0.00097, + utxoHash: "2305be66ab9648b713a58e3807fa1cba1f84e5d11359b316e967d98e9a7667da", + }, + expectedData{ + rate: 0.00098, + utxoHash: "030dc8a868a3e534799d465ebc8209eb32d9465985dc8c35e731b124bf3ffbcf", + }, + expectedData{ + rate: 0.00098, + utxoHash: "8222a9a43b3951f247612ddce2fe36f96cd843bc0dfef86c7d0ef5335331f11f", + }, + expectedData{ + rate: 0.00099, + utxoHash: "a40bd183cd2ff2b52faac5ebc2cfc1e36104cbc92bcebac011b45792b39e380e", + }, + expectedData{ + rate: 1.0009, + utxoHash: "118b2c40848887614d99b0e7eb6c88a10b47196e6aca3ff2eeab452bfdb9cfcb", + }, + expectedData{ + rate: 888888.7954, + utxoHash: "545a5c6f7ff9be19ed07a7246277c67d661f9cc7d8956bb81ce9a4045fba3720", + }, + expectedData{ + rate: 999999.9521, + utxoHash: "d9f7725d908510268c7bdecd29cb2031baab93b9bfa69108eb0a926ba7ae18f9", + }, + }, + }, + } + + for i, c := range cases { + for _, order := range c.orders { + data, err := json.Marshal(order.Utxo) + if err != nil { + t.Fatal(err) + } + utxoHash := bc.NewHash(sha3.Sum256(data)) + key := calcOrdersPrefix(order.FromAssetID, order.ToAssetID, &utxoHash, order.Rate) + db.SetSync(key, data) + } + + got := []expectedData{} + + itr := db.IteratorPrefixWithStart(nil, nil, false) + for itr.Next() { + key := itr.Key() + pos := len(ordersPreFix) + 32*2 + b := [32]byte{} + copy(b[:], key[pos+8:]) + utxoHash := bc.NewHash(b) + got = append(got, expectedData{ + rate: math.Float64frombits(binary.BigEndian.Uint64(key[pos : pos+8])), + utxoHash: utxoHash.String(), + }) + } + itr.Release() + + if !testutil.DeepEqual(c.want, got) { + t.Errorf("case %v: got recovery status, got: %v, want: %v.", i, got, c.want) + } + + } +} -- 2.11.0