}
func calcTradePairKey(fromAssetID, toAssetID *bc.AssetID) []byte {
- key := append(ordersPreFix, fromAssetID.Bytes()...)
+ key := append(tradePairPreFix, fromAssetID.Bytes()...)
return append(key, toAssetID.Bytes()...)
}
-type DexTradeOrderDB struct {
+type DexStore struct {
db dbm.DB
}
-func (d *DexTradeOrderDB) GetTradePairsWithStart(fromAssetID, toAssetID *bc.AssetID) ([]*common.TradePair, error) {
- startKey := []byte{}
- if fromAssetID != nil && toAssetID != nil {
- startKey = calcTradePairKey(fromAssetID, toAssetID)
+func NewDexStore(db dbm.DB) *DexStore {
+ return &DexStore{db: db}
+}
+
+func (d *DexStore) ListOrders(fromAssetID, toAssetID *bc.AssetID, rateAfter float64) ([]*common.Order, error) {
+ if fromAssetID == nil || toAssetID == nil {
+ return nil, errors.New("assetID is nil")
}
+ ordersPreFixLen := len(ordersPreFix)
+ orders := []*common.Order{}
- tradePairs := []*common.TradePair{}
- preFixLen := len(tradePairPreFix)
- itr := d.db.IteratorPrefixWithStart(tradePairPreFix, startKey, false)
+ orderPreFix := append(ordersPreFix, fromAssetID.Bytes()...)
+ orderPreFix = append(orderPreFix, toAssetID.Bytes()...)
+
+ var startKey []byte
+ if rateAfter > 0 {
+ buf := make([]byte, 8)
+ binary.BigEndian.PutUint64(buf, math.Float64bits(rateAfter))
+ copy(startKey, orderPreFix)
+ startKey = append(startKey, buf...)
+ }
+
+ itr := d.db.IteratorPrefixWithStart(orderPreFix, startKey, false)
defer itr.Release()
- for txNum := tradePairsNum; itr.Next() && txNum > 0; {
+ for txNum := ordersNum; itr.Next() && txNum > 0; {
key := itr.Key()
b := [32]byte{}
- fromAssetIDPos := preFixLen
+ fromAssetIDPos := ordersPreFixLen
copy(b[:], key[fromAssetIDPos:fromAssetIDPos+32])
fromAssetID := bc.NewAssetID(b)
- toAssetIDPos := preFixLen + 32
+ toAssetIDPos := ordersPreFixLen + 32
copy(b[:], key[toAssetIDPos:toAssetIDPos+32])
toAssetID := bc.NewAssetID(b)
- count := binary.BigEndian.Uint64(itr.Value())
-
- tradePairs = append(tradePairs, &common.TradePair{FromAssetID: &fromAssetID, ToAssetID: &toAssetID, Count: count})
-
- txNum--
- }
-
- return tradePairs, nil
-}
-
-func (d *DexTradeOrderDB) addTradePair(fromAssetID, toAssetID *bc.AssetID) error {
- count := uint64(0)
- key := calcTradePairKey(fromAssetID, toAssetID)
- if value := d.db.Get(key); value != nil {
- count = binary.BigEndian.Uint64(value)
- }
-
- count++
-
- value := [8]byte{}
- binary.BigEndian.PutUint64(value[:], count)
- d.db.Set(key, value[:])
- return nil
-}
+ ratePos := ordersPreFixLen + 32*2
+ rate := math.Float64frombits(binary.BigEndian.Uint64(key[ratePos : ratePos+8]))
-func (d *DexTradeOrderDB) deleteTradePair(fromAssetID, toAssetID *bc.AssetID) error {
- key := calcTradePairKey(fromAssetID, toAssetID)
- if value := d.db.Get(key); value != nil {
- count := binary.BigEndian.Uint64(value) - 1
+ dexUtxo := &common.DexUtxo{}
+ if err := json.Unmarshal(itr.Value(), dexUtxo); err != nil {
+ return nil, err
+ }
- if count > 0 {
- value := [8]byte{}
- binary.BigEndian.PutUint64(value[:], count)
- d.db.Set(key, value[:])
- } else {
- d.db.Delete(key)
+ order := &common.Order{
+ FromAssetID: &fromAssetID,
+ ToAssetID: &toAssetID,
+ Rate: rate,
+ Utxo: dexUtxo,
}
- return nil
+
+ orders = append(orders, order)
+ txNum--
}
- return errors.New("don't find trade pair")
+ return orders, nil
}
-func (d *DexTradeOrderDB) ProcessOrders(addOrders []*common.Order, delOreders []*common.Order, height uint64, blockHash *bc.Hash) error {
+func (d *DexStore) ProcessOrders(addOrders []*common.Order, delOreders []*common.Order, height uint64, blockHash *bc.Hash) error {
batch := d.db.NewBatch()
if err := d.addOrders(batch, addOrders); err != nil {
return nil
}
-func (d *DexTradeOrderDB) addOrders(batch dbm.Batch, orders []*common.Order) error {
+func (d *DexStore) addOrders(batch dbm.Batch, orders []*common.Order) error {
+ tradePairMap := make(map[common.TradePair]uint64)
for _, order := range orders {
data, err := json.Marshal(order.Utxo)
if err != nil {
return err
}
+
utxoHash := bc.NewHash(sha3.Sum256(data))
key := calcOrdersKey(order.FromAssetID, order.ToAssetID, &utxoHash, order.Rate)
batch.Set(key, data)
- if err := d.addTradePair(order.FromAssetID, order.ToAssetID); err != nil {
- return err
+ tradePair := common.TradePair{
+ FromAssetID: order.FromAssetID,
+ ToAssetID: order.ToAssetID,
}
+ tradePairMap[tradePair] += 1
+ }
+
+ if err := d.addTradePair(batch, tradePairMap); err != nil {
+ return err
}
return nil
}
-func (d *DexTradeOrderDB) deleteOrder(batch dbm.Batch, orders []*common.Order) error {
+func (d *DexStore) deleteOrder(batch dbm.Batch, orders []*common.Order) error {
+ tradePairMap := make(map[common.TradePair]uint64)
for _, order := range orders {
data, err := json.Marshal(order.Utxo)
if err != nil {
return err
}
+
utxoHash := bc.NewHash(sha3.Sum256(data))
key := calcOrdersKey(order.FromAssetID, order.ToAssetID, &utxoHash, order.Rate)
batch.Delete(key)
-
- if err := d.deleteTradePair(order.FromAssetID, order.ToAssetID); err != nil {
- return err
+ tradePair := common.TradePair{
+ FromAssetID: order.FromAssetID,
+ ToAssetID: order.ToAssetID,
}
+ tradePairMap[tradePair] += 1
+ }
+
+ if err := d.deleteTradePair(batch, tradePairMap); err != nil {
+ return err
}
return nil
}
-func (d *DexTradeOrderDB) ListOrders(fromAssetID, toAssetID *bc.AssetID, rateAfter float64) ([]*common.Order, error) {
- ordersPreFixLen := len(ordersPreFix)
- orders := []*common.Order{}
+func (d *DexStore) GetDexDatabaseState() (*common.DexDatabaseState, error) {
+ value := d.db.Get(bestMatchStore)
+ if value != nil {
+ return nil, errors.New("don't find state of dex-database")
+ }
- orderPreFix := append(ordersPreFix, fromAssetID.Bytes()...)
- orderPreFix = append(orderPreFix, toAssetID.Bytes()...)
+ state := &common.DexDatabaseState{}
+ if err := json.Unmarshal(value, state); err != nil {
+ return nil, err
+ }
- startKey := []byte{}
- buf := make([]byte, 8)
- binary.BigEndian.PutUint64(buf, math.Float64bits(rateAfter))
- copy(startKey, orderPreFix)
- startKey = append(startKey, buf...)
+ return state, nil
+}
- itr := d.db.IteratorPrefixWithStart(orderPreFix, startKey, false)
+func (d *DexStore) ListTradePairsWithStart(fromAssetID, toAssetID *bc.AssetID) ([]*common.TradePair, error) {
+ var startKey []byte
+ if fromAssetID != nil && toAssetID != nil {
+ startKey = calcTradePairKey(fromAssetID, toAssetID)
+ }
+
+ tradePairs := []*common.TradePair{}
+ preFixLen := len(tradePairPreFix)
+ itr := d.db.IteratorPrefixWithStart(tradePairPreFix, startKey, false)
defer itr.Release()
- for txNum := ordersNum; itr.Next() && txNum > 0; {
+ for txNum := tradePairsNum; itr.Next() && txNum > 0; {
key := itr.Key()
b := [32]byte{}
- fromAssetIDPos := ordersPreFixLen
+ fromAssetIDPos := preFixLen
copy(b[:], key[fromAssetIDPos:fromAssetIDPos+32])
fromAssetID := bc.NewAssetID(b)
- toAssetIDPos := ordersPreFixLen + 32
+ toAssetIDPos := preFixLen + 32
copy(b[:], key[toAssetIDPos:toAssetIDPos+32])
toAssetID := bc.NewAssetID(b)
- ratePos := ordersPreFixLen + 32*2
- rate := math.Float64frombits(binary.BigEndian.Uint64(key[ratePos : ratePos+8]))
-
- dexUtxo := &common.DexUtxo{}
- if err := json.Unmarshal(itr.Value(), dexUtxo); err != nil {
- return nil, err
- }
+ count := binary.BigEndian.Uint64(itr.Value())
- order := &common.Order{
- FromAssetID: &fromAssetID,
- ToAssetID: &toAssetID,
- Rate: rate,
- Utxo: dexUtxo,
- }
+ tradePairs = append(tradePairs, &common.TradePair{FromAssetID: &fromAssetID, ToAssetID: &toAssetID, Count: count})
- orders = append(orders, order)
txNum--
}
- return orders, nil
+ return tradePairs, nil
}
-func (d *DexTradeOrderDB) GetDexDatabaseState() (*common.DexDatabaseState, error) {
- value := d.db.Get(bestMatchStore)
- if value != nil {
- return nil, errors.New("don't find state of dex-database")
+func (d *DexStore) addTradePair(batch dbm.Batch, tradePairMap map[common.TradePair]uint64) error {
+ for k, v := range tradePairMap {
+ count := uint64(0)
+ key := calcTradePairKey(k.FromAssetID, k.ToAssetID)
+ if value := d.db.Get(key); value != nil {
+ count = binary.BigEndian.Uint64(value)
+ }
+
+ count += v
+
+ value := [8]byte{}
+ binary.BigEndian.PutUint64(value[:], count)
+ batch.Set(key, value[:])
}
+ return nil
+}
- state := &common.DexDatabaseState{}
- if err := json.Unmarshal(value, state); err != nil {
- return nil, err
+func (d *DexStore) deleteTradePair(batch dbm.Batch, tradePairMap map[common.TradePair]uint64) error {
+ for k, v := range tradePairMap {
+ key := calcTradePairKey(k.FromAssetID, k.ToAssetID)
+ value := d.db.Get(key)
+ if value == nil {
+ return errors.New("don't find trade pair")
+ }
+ count := binary.BigEndian.Uint64(value) - v
+
+ if count > 0 {
+ value := [8]byte{}
+ binary.BigEndian.PutUint64(value[:], count)
+ batch.Set(key, value[:])
+ } else {
+ batch.Delete(key)
+ }
}
- return state, nil
+ return nil
}
-func (d *DexTradeOrderDB) saveDexDatabaseState(batch dbm.Batch, state *common.DexDatabaseState) error {
+func (d *DexStore) saveDexDatabaseState(batch dbm.Batch, state *common.DexDatabaseState) error {
value, err := json.Marshal(state)
if err != nil {
return err
"github.com/vapor/application/dex/common"
"github.com/vapor/database/leveldb"
+ dbm "github.com/vapor/database/leveldb"
"github.com/vapor/protocol/bc"
"github.com/vapor/testutil"
)
t.Fatal(err)
}
utxoHash := bc.NewHash(sha3.Sum256(data))
- key := calcOrdersPrefix(order.FromAssetID, order.ToAssetID, &utxoHash, order.Rate)
+ key := calcOrdersKey(order.FromAssetID, order.ToAssetID, &utxoHash, order.Rate)
db.SetSync(key, data)
}
}
}
+
+func TestDexStore(t *testing.T) {
+
+ assetID1 := &bc.AssetID{V0: 1}
+ assetID2 := &bc.AssetID{V0: 2}
+
+ cases := []struct {
+ desc string
+ beforeOrders []*common.Order
+ addOrders []*common.Order
+ delOrders []*common.Order
+ Height uint64
+ blockHash *bc.Hash
+ wantOrders []*common.Order
+ wantTradePairs []*common.TradePair
+ }{
+ {
+ desc: "add order",
+ addOrders: []*common.Order{
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 1.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 21},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 22},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00097,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 23},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 13},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 10,
+ SourcePos: 1,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00099,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00096,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 25},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00095,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 26},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ },
+ Height: 10,
+ blockHash: &bc.Hash{},
+ wantOrders: []*common.Order{
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 22},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00095,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 26},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00096,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 25},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00097,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 23},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 13},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 10,
+ SourcePos: 1,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00099,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 1.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 21},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ },
+ wantTradePairs: []*common.TradePair{
+ &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 8},
+ },
+ },
+ {
+ desc: "del some order",
+ beforeOrders: []*common.Order{
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 1.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 21},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 22},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00097,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 23},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 13},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 10,
+ SourcePos: 1,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00099,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00096,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 25},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00095,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 26},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ },
+ delOrders: []*common.Order{
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 1.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 21},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 22},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00097,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 23},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ },
+ Height: 10,
+ blockHash: &bc.Hash{},
+ wantOrders: []*common.Order{
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00095,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 26},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00096,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 25},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 13},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 10,
+ SourcePos: 1,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00099,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ },
+ wantTradePairs: []*common.TradePair{
+ &common.TradePair{FromAssetID: assetID1, ToAssetID: assetID2, Count: 5},
+ },
+ },
+
+ {
+ desc: "del all order",
+ beforeOrders: []*common.Order{
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 1.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 21},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 22},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00097,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 23},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 13},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 10,
+ SourcePos: 1,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00099,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00096,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 25},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00095,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 26},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ },
+ delOrders: []*common.Order{
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 1.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 21},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00090,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 22},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00097,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 23},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 13},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00098,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 10,
+ SourcePos: 1,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00099,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 24},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00096,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 25},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ &common.Order{
+ FromAssetID: assetID1,
+ ToAssetID: assetID2,
+ Rate: 0.00095,
+ Utxo: &common.DexUtxo{
+ SourceID: &bc.Hash{V0: 26},
+ Amount: 1,
+ SourcePos: 0,
+ ControlProgram: []byte("aa"),
+ },
+ },
+ },
+ Height: 10,
+ blockHash: &bc.Hash{},
+ wantOrders: []*common.Order{},
+ wantTradePairs: []*common.TradePair{},
+ },
+ }
+ defer os.RemoveAll("temp")
+ for i, c := range cases {
+ testDB := dbm.NewDB("testdb", "leveldb", "temp")
+ dexStore := NewDexStore(testDB)
+
+ batch := dexStore.db.NewBatch()
+ dexStore.addOrders(batch, c.beforeOrders)
+ batch.Write()
+
+ if err := dexStore.ProcessOrders(c.addOrders, c.delOrders, c.Height, c.blockHash); err != nil {
+ t.Fatalf("case %v: ProcessOrders error %v.", i, err)
+ }
+
+ gotOrders, err := dexStore.ListOrders(assetID1, assetID2, 0)
+ if err != nil {
+ t.Fatalf("case %v: ListOrders error %v.", i, err)
+ }
+
+ if !testutil.DeepEqual(gotOrders, c.wantOrders) {
+ t.Fatalf("case %v: got orders , gotOrders: %v, wantOrders: %v.", i, gotOrders, c.wantOrders)
+ }
+
+ gotTradePairs, err := dexStore.ListTradePairsWithStart(nil, nil)
+ if err != nil {
+ t.Fatalf("case %v: GetDexDatabaseState error %v.", i, err)
+ }
+
+ if !testutil.DeepEqual(gotTradePairs, c.wantTradePairs) {
+ t.Fatalf("case %v: got tradePairs, gotTradePairs: %v, wantTradePairs: %v.", i, gotTradePairs, c.wantTradePairs)
+ }
+
+ testDB.Close()
+ os.RemoveAll("temp")
+ }
+}