Commit ef3012f1 authored by harrylee's avatar harrylee Committed by vipwzw

ajust sotage struct

parent ca3650a2
...@@ -11,7 +11,6 @@ import ( ...@@ -11,7 +11,6 @@ import (
"github.com/33cn/chain33/client" "github.com/33cn/chain33/client"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto" "github.com/33cn/chain33/common/crypto"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/queue" "github.com/33cn/chain33/queue"
et "github.com/33cn/plugin/plugin/dapp/exchange/types" et "github.com/33cn/plugin/plugin/dapp/exchange/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
...@@ -62,9 +61,11 @@ func TestExchange(t *testing.T) { ...@@ -62,9 +61,11 @@ func TestExchange(t *testing.T) {
Frozen: 0, Frozen: 0,
Addr: string(Nodes[3]), Addr: string(Nodes[3]),
} }
dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb)
execAddr := address.ExecAddress(et.ExchangeX) execAddr := address.ExecAddress(et.ExchangeX)
stateDB, _ := dbm.NewGoMemDB("1", "2", 5000) //stateDB, _ := dbm.NewGoMemDB("1", "2", 5000)
_, _, kvdb := util.CreateTestDB() _, stateDB, kvdb := util.CreateTestDB()
accA, _ := account.NewAccountDB(cfg, "coins", "bty", stateDB) accA, _ := account.NewAccountDB(cfg, "coins", "bty", stateDB)
accA.SaveExecAccount(execAddr, &accountA) accA.SaveExecAccount(execAddr, &accountA)
...@@ -104,6 +105,7 @@ func TestExchange(t *testing.T) { ...@@ -104,6 +105,7 @@ func TestExchange(t *testing.T) {
tx, err = types.FormatTx(cfg, et.ExchangeX, tx) tx, err = types.FormatTx(cfg, et.ExchangeX, tx)
assert.Nil(t, err) assert.Nil(t, err)
tx, err = signTx(tx, PrivKeyA) tx, err = signTx(tx, PrivKeyA)
t.Log(tx)
assert.Nil(t, err) assert.Nil(t, err)
exec := newExchange() exec := newExchange()
e := exec.(*exchange) e := exec.(*exchange)
...@@ -134,9 +136,19 @@ func TestExchange(t *testing.T) { ...@@ -134,9 +136,19 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
orderID1 := common.ToHex(tx.Hash()) //save to database
util.SaveKVList(stateDB, set.KV)
assert.Equal(t, types.ExecOk, int(receipt.Ty))
//根据地址状态查看订单,最新得订单号永远是在list[0],第一位
msg, err := exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Ordered, Address: string(Nodes[0])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply2 := msg.(*et.OrderList)
orderID1 := reply2.List[0].OrderID
//根据订单号,查询订单详情 //根据订单号,查询订单详情
msg, err := exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID1})) msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID1}))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
...@@ -158,16 +170,6 @@ func TestExchange(t *testing.T) { ...@@ -158,16 +170,6 @@ func TestExchange(t *testing.T) {
reply1 := msg.(*et.MarketDepthList) reply1 := msg.(*et.MarketDepthList)
assert.Equal(t, 10*types.Coin, reply1.List[0].GetAmount()) assert.Equal(t, 10*types.Coin, reply1.List[0].GetAmount())
//根据状态和地址查询
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Ordered, Address: string(Nodes[0])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply2 := msg.(*et.OrderList)
assert.Equal(t, orderID1, reply2.List[0].OrderID)
// orderlimit bty:CCNY 卖bty // orderlimit bty:CCNY 卖bty
tx, err = ety.Create("LimitOrder", &et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, tx, err = ety.Create("LimitOrder", &et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: 4, Amount: 5 * types.Coin, Op: et.OpSell}) RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: 4, Amount: 5 * types.Coin, Op: et.OpSell})
...@@ -197,7 +199,17 @@ func TestExchange(t *testing.T) { ...@@ -197,7 +199,17 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
orderID2 := common.ToHex(tx.Hash()) //save to database
util.SaveKVList(stateDB, set.KV)
assert.Equal(t, types.ExecOk, int(receipt.Ty))
//根据地址状态查看订单
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Completed, Address: string(Nodes[1])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
orderList := msg.(*et.OrderList)
orderID2 := orderList.List[0].OrderID
//根据订单号,查询订单详情 //根据订单号,查询订单详情
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID1})) msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID1}))
if err != nil { if err != nil {
...@@ -266,6 +278,8 @@ func TestExchange(t *testing.T) { ...@@ -266,6 +278,8 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
//save to database
util.SaveKVList(stateDB, set.KV)
//根据订单号,查询订单详情 //根据订单号,查询订单详情
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID1})) msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID1}))
if err != nil { if err != nil {
...@@ -314,7 +328,17 @@ func TestExchange(t *testing.T) { ...@@ -314,7 +328,17 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
orderID3 := common.ToHex(tx.Hash()) //save to database
util.SaveKVList(stateDB, set.KV)
assert.Equal(t, types.ExecOk, int(receipt.Ty))
//根据地址状态查看订单
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Ordered, Address: string(Nodes[0])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
orderList = msg.(*et.OrderList)
orderID3 := orderList.List[0].OrderID
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID3})) msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID3}))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
...@@ -352,7 +376,16 @@ func TestExchange(t *testing.T) { ...@@ -352,7 +376,16 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
orderID4 := common.ToHex(tx.Hash()) //save to database
util.SaveKVList(stateDB, set.KV)
//根据地址状态查看订单
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Ordered, Address: string(Nodes[0])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
orderList = msg.(*et.OrderList)
orderID4 := orderList.List[0].OrderID
//根据订单号,查询订单详情 //根据订单号,查询订单详情
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID4})) msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID4}))
if err != nil { if err != nil {
...@@ -412,8 +445,16 @@ func TestExchange(t *testing.T) { ...@@ -412,8 +445,16 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
orderID5 := common.ToHex(tx.Hash()) //save to database
util.SaveKVList(stateDB, set.KV)
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Completed, Address: string(Nodes[1])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
orderList = msg.(*et.OrderList)
orderID5 := orderList.List[0].OrderID
//
//根据订单号,查询订单详情 //根据订单号,查询订单详情
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID5})) msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID5}))
if err != nil { if err != nil {
...@@ -426,13 +467,11 @@ func TestExchange(t *testing.T) { ...@@ -426,13 +467,11 @@ func TestExchange(t *testing.T) {
msg, err = exec.Query(et.FuncNameQueryMarketDepth, types.Encode(&et.QueryMarketDepth{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, msg, err = exec.Query(et.FuncNameQueryMarketDepth, types.Encode(&et.QueryMarketDepth{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "paracross", Symbol: "coins.bty"}, Op: et.OpSell})) RightAsset: &et.Asset{Execer: "paracross", Symbol: "coins.bty"}, Op: et.OpSell}))
if err != nil { if err != nil {
t.Error(err) assert.Equal(t, types.ErrNotFound, err)
} }
reply1 = msg.(*et.MarketDepthList)
t.Log(reply1.List)
//根据状态和地址查询 ////根据状态和地址查询
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Completed, Address: string(Nodes[0])})) msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Completed, Address: string(Nodes[1])}))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
...@@ -476,7 +515,16 @@ func TestExchange(t *testing.T) { ...@@ -476,7 +515,16 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
orderID6 := common.ToHex(tx.Hash()) //save to database
util.SaveKVList(stateDB, set.KV)
//根据地址状态查看订单
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Ordered, Address: string(Nodes[3])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
orderList = msg.(*et.OrderList)
orderID6 := orderList.List[0].OrderID
//根据订单号,查询订单详情 //根据订单号,查询订单详情
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID6})) msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID6}))
if err != nil { if err != nil {
...@@ -513,9 +561,18 @@ func TestExchange(t *testing.T) { ...@@ -513,9 +561,18 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
orderID7 := common.ToHex(tx.Hash())
//根据订单号,查询订单详情
//save to database
util.SaveKVList(stateDB, set.KV)
//根据地址状态查看订单
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Ordered, Address: string(Nodes[2])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
orderList = msg.(*et.OrderList)
orderID7 := orderList.List[0].OrderID
//根据订单号,查询订单详情
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID6})) msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID6}))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
...@@ -535,7 +592,6 @@ func TestExchange(t *testing.T) { ...@@ -535,7 +592,6 @@ func TestExchange(t *testing.T) {
assert.Equal(t, 85*types.Coin, acc.Balance) assert.Equal(t, 85*types.Coin, acc.Balance)
acc = accC.LoadExecAccount(string(Nodes[2]), execAddr) acc = accC.LoadExecAccount(string(Nodes[2]), execAddr)
t.Log(acc) t.Log(acc)
// orderlimit bty:CCNY ,先挂卖单,然后高于市场价格买入, 买家获利原则 // orderlimit bty:CCNY ,先挂卖单,然后高于市场价格买入, 买家获利原则
tx, err = ety.Create("LimitOrder", &et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, tx, err = ety.Create("LimitOrder", &et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
...@@ -567,7 +623,16 @@ func TestExchange(t *testing.T) { ...@@ -567,7 +623,16 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
orderID8 := common.ToHex(tx.Hash()) //save to database
util.SaveKVList(stateDB, set.KV)
//根据地址状态查看订单
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Ordered, Address: string(Nodes[2])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
orderList = msg.(*et.OrderList)
orderID8 := orderList.List[0].OrderID
tx, err = ety.Create("LimitOrder", &et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, tx, err = ety.Create("LimitOrder", &et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: 5, Amount: 5 * types.Coin, Op: et.OpSell}) RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: 5, Amount: 5 * types.Coin, Op: et.OpSell})
...@@ -598,7 +663,16 @@ func TestExchange(t *testing.T) { ...@@ -598,7 +663,16 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
orderID9 := common.ToHex(tx.Hash()) //save to database
util.SaveKVList(stateDB, set.KV)
//根据地址状态查看订单
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Ordered, Address: string(Nodes[2])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
orderList = msg.(*et.OrderList)
orderID9 := orderList.List[0].OrderID
tx, err = ety.Create("LimitOrder", &et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, tx, err = ety.Create("LimitOrder", &et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: 4.5, Amount: 15 * types.Coin, Op: et.OpBuy}) RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: 4.5, Amount: 15 * types.Coin, Op: et.OpBuy})
assert.Nil(t, err) assert.Nil(t, err)
...@@ -627,7 +701,16 @@ func TestExchange(t *testing.T) { ...@@ -627,7 +701,16 @@ func TestExchange(t *testing.T) {
for _, kv := range set.KV { for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value) kvdb.Set(kv.Key, kv.Value)
} }
orderID10 := common.ToHex(tx.Hash()) //save to database
util.SaveKVList(stateDB, set.KV)
//根据地址状态查看订单
msg, err = exec.Query(et.FuncNameQueryOrderList, types.Encode(&et.QueryOrderList{Status: et.Ordered, Address: string(Nodes[3])}))
if err != nil {
t.Error(err)
}
t.Log(msg)
orderList = msg.(*et.OrderList)
orderID10 := orderList.List[0].OrderID
//根据订单号,查询订单详情 //根据订单号,查询订单详情
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID7})) msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID7}))
if err != nil { if err != nil {
...@@ -703,3 +786,19 @@ func TestCheckPrice(t *testing.T) { ...@@ -703,3 +786,19 @@ func TestCheckPrice(t *testing.T) {
t.Log(CheckPrice(Truncate(float64(1e-8)))) t.Log(CheckPrice(Truncate(float64(1e-8))))
t.Log(CheckPrice(Truncate(float64(1e-9)))) t.Log(CheckPrice(Truncate(float64(1e-9))))
} }
func TestRawMeta(t *testing.T) {
CompletedOrderRow := NewCompletedOrderRow()
t.Log(CompletedOrderRow.Get("index"))
MarketDepthRow := NewMarketDepthRow()
t.Log(MarketDepthRow.Get("price"))
marketOrderRow := NewOrderRow()
t.Log(marketOrderRow.Get("orderID"))
UserOrderRow := NewUserOrderRow()
t.Log(UserOrderRow.Get("index"))
}
func TestKV(t *testing.T) {
a := &types.KeyValue{Key: []byte("1111111"), Value: nil}
t.Log(a.Key, a.Value)
}
...@@ -6,12 +6,12 @@ import ( ...@@ -6,12 +6,12 @@ import (
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
"github.com/33cn/chain33/client" "github.com/33cn/chain33/client"
"github.com/33cn/chain33/common" //"github.com/33cn/chain33/common"
dbm "github.com/33cn/chain33/common/db" dbm "github.com/33cn/chain33/common/db"
. "github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/system/dapp" "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
et "github.com/33cn/plugin/plugin/dapp/exchange/types" et "github.com/33cn/plugin/plugin/dapp/exchange/types"
"github.com/gogo/protobuf/proto"
) )
// Action action struct // Action action struct
...@@ -22,7 +22,7 @@ type Action struct { ...@@ -22,7 +22,7 @@ type Action struct {
blocktime int64 blocktime int64
height int64 height int64
execaddr string execaddr string
localDB dbm.Lister localDB dbm.KVDB
index int index int
api client.QueueProtocolAPI api client.QueueProtocolAPI
} }
...@@ -170,7 +170,8 @@ func (a *Action) LimitOrder(payload *et.LimitOrder) (*types.Receipt, error) { ...@@ -170,7 +170,8 @@ func (a *Action) LimitOrder(payload *et.LimitOrder) (*types.Receipt, error) {
func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) { func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kvs []*types.KeyValue var kvs []*types.KeyValue
order, err := findOrderByOrderID(a.statedb, payload.GetOrderID()) order, err := findOrderByOrderID(a.statedb, a.localDB, payload.GetOrderID())
elog.Info("RevokeOrder====", "order", order.Balance)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -252,12 +253,12 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) { ...@@ -252,12 +253,12 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAccountDB *account.DB) (*types.Receipt, error) { func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAccountDB *account.DB) (*types.Receipt, error) {
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kvs []*types.KeyValue var kvs []*types.KeyValue
var index int64 var orderKey string
var price float64 var priceKey string
var count int var count int
or := &et.Order{ or := &et.Order{
OrderID: common.ToHex(a.txhash), OrderID: a.GetIndex(),
Value: &et.Order_LimitOrder{LimitOrder: payload}, Value: &et.Order_LimitOrder{LimitOrder: payload},
Ty: et.TyLimitOrderAction, Ty: et.TyLimitOrderAction,
Executed: 0, Executed: 0,
...@@ -278,7 +279,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -278,7 +279,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
if count > et.MaxCount { if count > et.MaxCount {
break break
} }
marketDepthList, err := QueryMarketDepth(a.localDB, payload.GetLeftAsset(), payload.GetRightAsset(), a.OpSwap(payload.Op), price, et.Count) marketDepthList, err := QueryMarketDepth(a.localDB, payload.GetLeftAsset(), payload.GetRightAsset(), a.OpSwap(payload.Op), priceKey, et.Count)
if err == types.ErrNotFound { if err == types.ErrNotFound {
break break
} }
...@@ -297,21 +298,15 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -297,21 +298,15 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
} }
//根据价格进行迭代 //根据价格进行迭代
for { for {
orderIDs, err := findOrderIDListByPrice(a.localDB, payload.GetLeftAsset(), payload.GetRightAsset(), marketDepth.Price, a.OpSwap(payload.Op), et.ListASC, index) orderList, err := findOrderIDListByPrice(a.localDB, payload.GetLeftAsset(), payload.GetRightAsset(), marketDepth.Price, a.OpSwap(payload.Op), et.ListASC, orderKey)
if err == types.ErrNotFound { if err == types.ErrNotFound {
continue break
} }
for _, orderID := range orderIDs { for _, matchorder := range orderList.List {
matchorder, err := findOrderByOrderID(a.statedb, orderID.ID)
if err != nil {
elog.Warn("matchLimitOrder.findOrderByOrderID", "order", "err", err.Error())
continue
}
//同地址不能交易 //同地址不能交易
if matchorder.Addr == a.fromaddr { if matchorder.Addr == a.fromaddr {
continue continue
} }
//TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生 //TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生
if matchorder.GetBalance() >= or.GetBalance() { if matchorder.GetBalance() >= or.GetBalance() {
if payload.Op == et.OpSell { if payload.Op == et.OpSell {
...@@ -461,18 +456,18 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -461,18 +456,18 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
count = count + 1 count = count + 1
} }
//查询数据不满足5条说明没有了,跳出循环 //查询数据不满足5条说明没有了,跳出循环
if len(orderIDs) < int(et.Count) { if orderList.PrimaryKey == "" {
break break
} }
index = orderIDs[len(orderIDs)-1].Index orderKey = orderList.PrimaryKey
} }
} }
//查询数据不满足5条说明没有了,跳出循环 //查询数据不满足5条说明没有了,跳出循环
if len(marketDepthList.List) < int(et.Count) { if marketDepthList.PrimaryKey == "" {
break break
} }
price = marketDepthList.List[len(marketDepthList.List)-1].Price priceKey = marketDepthList.PrimaryKey
} }
//冻结剩余未成交的资金 //冻结剩余未成交的资金
...@@ -501,55 +496,60 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -501,55 +496,60 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
receipts := &types.Receipt{Ty: types.ExecOk, KV: kvs, Logs: logs} receipts := &types.Receipt{Ty: types.ExecOk, KV: kvs, Logs: logs}
return receipts, nil return receipts, nil
} }
func findOrderByOrderID(statedb dbm.KV, orderID string) (*et.Order, error) {
data, err := statedb.Get(calcOrderKey(orderID)) //根据订单号查询,分为两步,优先去localdb中查询,如没有则再去状态数据库中查询
if err != nil { // 1.挂单中得订单信会根据orderID在localdb中存储
elog.Error("findOrderByOrderID.Get", "orderID", orderID, "err", err.Error()) // 2.订单撤销,或者成交后,根据orderID在localdb中存储得数据会被删除,这时只能到状态数据库中查询
return nil, err func findOrderByOrderID(statedb dbm.KV, localdb dbm.KVDB, orderID int64) (*et.Order, error) {
} table := NewMarketOrderTable(localdb)
var order et.Order primaryKey := []byte(fmt.Sprintf("%022d", orderID))
err = types.Decode(data, &order) row, err := table.GetData(primaryKey)
if err != nil { if err != nil {
elog.Error("findOrderByOrderID.Decode", "orderID", orderID, "err", err.Error()) data, err := statedb.Get(calcOrderKey(orderID))
return nil, err if err != nil {
elog.Error("findOrderByOrderID.Get", "orderID", orderID, "err", err.Error())
return nil, err
}
var order et.Order
err = types.Decode(data, &order)
if err != nil {
elog.Error("findOrderByOrderID.Decode", "orderID", orderID, "err", err.Error())
return nil, err
}
return &order, nil
} }
return &order, nil return row.Data.(*et.Order), nil
} }
func findOrderIDListByPrice(localdb dbm.Lister, left, right *et.Asset, price float64, op, direction int32, index int64) ([]*et.OrderID, error) { func findOrderIDListByPrice(localdb dbm.KVDB, left, right *et.Asset, price float64, op, direction int32, primaryKey string) (*et.OrderList, error) {
prefix := calcMarketDepthOrderPrefix(left, right, op, price) table := NewMarketOrderTable(localdb)
key := calcMarketDepthOrderKey(left, right, op, price, index) query := table.GetQuery(localdb)
var values [][]byte prefix := []byte(fmt.Sprintf("%s:%s:%d:%016d", left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price*float64(1e8)))))
var rows []*Row
var err error var err error
if index == 0 { //第一次查询 if primaryKey == "" { //第一次查询,默认展示最新得成交记录
values, err = localdb.List(prefix, nil, et.Count, direction) rows, err = query.ListIndex("market_order", prefix, nil, et.Count, direction)
} else { } else {
values, err = localdb.List(prefix, key, et.Count, direction) rows, err = query.ListIndex("market_order", prefix, []byte(primaryKey), et.Count, direction)
} }
if err != nil { if err != nil {
elog.Error("findOrderIDListByPrice.", "left", left, "right", right, "price", price, "err", err.Error())
return nil, err return nil, err
} }
var list []*et.OrderID var orderList et.OrderList
for _, value := range values { for _, row := range rows {
var orderID et.OrderID order := row.Data.(*et.Order)
err := types.Decode(value, &orderID) //替换已经成交得量
if err != nil { order.Executed = order.GetLimitOrder().Amount - order.Balance
elog.Warn("findOrderIDListByPrice.Decode", "orderID", "err", err.Error()) orderList.List = append(orderList.List, order)
continue
}
list = append(list, &orderID)
} }
return list, nil //设置主键索引
} if len(rows) == int(et.Count) {
orderList.PrimaryKey = string(rows[len(rows)-1].Primary)
//localdb查询
func findObject(localdb dbm.KVDB, key []byte, msg proto.Message) error {
value, err := localdb.Get(key)
if err != nil {
elog.Warn("findObject.Decode", "key", string(key), "err", err.Error())
return err
} }
return types.Decode(value, msg) return &orderList, nil
} }
//买单深度是按价格倒序,由高到低 //买单深度是按价格倒序,由高到低
...@@ -560,112 +560,114 @@ func Direction(op int32) int32 { ...@@ -560,112 +560,114 @@ func Direction(op int32) int32 {
return et.ListASC return et.ListASC
} }
//这里price当作索引来用,首次查询不需要填值 //这里primaryKey当作主键索引来用,首次查询不需要填值
func QueryMarketDepth(localdb dbm.Lister, left, right *et.Asset, op int32, price float64, count int32) (*et.MarketDepthList, error) { func QueryMarketDepth(localdb dbm.KVDB, left, right *et.Asset, op int32, primaryKey string, count int32) (*et.MarketDepthList, error) {
prefix := calcMarketDepthPrefix(left, right, op) table := NewMarketDepthTable(localdb)
key := calcMarketDepthKey(left, right, op, price) query := table.GetQuery(localdb)
var values [][]byte prefix := []byte(fmt.Sprintf("%s:%s:%d", left.GetSymbol(), right.GetSymbol(), op))
if count == 0 {
count = et.Count
}
var rows []*Row
var err error var err error
if price == 0 { //第一次查询,方向卖单由低到高,买单由高到低 if primaryKey == "" { //第一次查询,默认展示最新得成交记录
values, err = localdb.List(prefix, nil, count, Direction(op)) rows, err = query.ListIndex("price", prefix, nil, count, Direction(op))
} else { } else {
values, err = localdb.List(prefix, key, count, Direction(op)) rows, err = query.ListIndex("price", prefix, []byte(primaryKey), count, Direction(op))
} }
if err != nil { if err != nil {
elog.Error("QueryMarketDepth.", "left", left, "right", right, "err", err.Error())
return nil, err return nil, err
} }
var list et.MarketDepthList var list et.MarketDepthList
for _, value := range values { for _, row := range rows {
var marketDept et.MarketDepth list.List = append(list.List, row.Data.(*et.MarketDepth))
err := types.Decode(value, &marketDept) }
if err != nil { //设置主键索引
elog.Warn("QueryMarketDepth.Decode", "marketDept", "err", err.Error()) if len(rows) == int(count) {
continue list.PrimaryKey = string(rows[len(rows)-1].Primary)
}
list.List = append(list.List, &marketDept)
} }
return &list, nil return &list, nil
} }
//QueryCompletedOrderList //QueryCompletedOrderList
func QueryCompletedOrderList(localdb dbm.Lister, statedb dbm.KV, left, right *et.Asset, index int64, count, direction int32) (types.Message, error) { func QueryCompletedOrderList(localdb dbm.KVDB, left, right *et.Asset, primaryKey string, count, direction int32) (types.Message, error) {
prefix := calcCompletedOrderPrefix(left, right) table := NewCompletedOrderTable(localdb)
key := calcCompletedOrderKey(left, right, index) query := table.GetQuery(localdb)
var values [][]byte prefix := []byte(fmt.Sprintf("%s:%s", left.Symbol, right.Symbol))
if count == 0 {
count = et.Count
}
var rows []*Row
var err error var err error
if index == 0 { //第一次查询,默认展示最新得成交记录 if primaryKey == "" { //第一次查询,默认展示最新得成交记录
values, err = localdb.List(prefix, nil, count, direction) rows, err = query.ListIndex("index", prefix, nil, count, direction)
} else { } else {
values, err = localdb.List(prefix, key, count, direction) rows, err = query.ListIndex("index", prefix, []byte(primaryKey), count, direction)
} }
if err != nil { if err != nil {
elog.Error("QueryCompletedOrderList.", "left", left, "right", right, "err", err.Error())
return nil, err return nil, err
} }
var list []*et.OrderID
for _, value := range values {
var orderID et.OrderID
err := types.Decode(value, &orderID)
if err != nil {
elog.Warn("QueryCompletedOrderList.Decode", "marketDept", "err", err.Error())
continue
}
list = append(list, &orderID)
}
var orderList et.OrderList var orderList et.OrderList
for _, orderID := range list { for _, row := range rows {
order, err := findOrderByOrderID(statedb, orderID.ID) order := row.Data.(*et.Order)
if err != nil {
continue
}
//替换索引index
order.Index = orderID.Index
//替换已经成交得量 //替换已经成交得量
order.Executed = order.GetLimitOrder().Amount - order.Balance order.Executed = order.GetLimitOrder().Amount - order.Balance
orderList.List = append(orderList.List, order) orderList.List = append(orderList.List, order)
} }
//设置主键索引
if len(rows) == int(count) {
orderList.PrimaryKey = string(rows[len(rows)-1].Primary)
}
return &orderList, nil return &orderList, nil
} }
//QueryOrderList,默认展示最新的 //QueryOrderList,默认展示最新的
func QueryOrderList(localdb dbm.Lister, statedb dbm.KV, addr string, status, count, direction int32, index int64) (types.Message, error) { func QueryOrderList(localdb dbm.KVDB, statedb dbm.KV, addr string, status, count, direction int32, primaryKey string) (types.Message, error) {
prefix := calcUserOrderIDPrefix(status, addr) table := NewUserOrderTable(localdb)
key := calcUserOrderIDKey(status, addr, index) query := table.GetQuery(localdb)
var values [][]byte prefix := []byte(fmt.Sprintf("%s:%d", addr, status))
if count == 0 {
count = et.Count
}
var rows []*Row
var err error var err error
if index == 0 { //第一次查询,默认展示最新得成交记录 if primaryKey == "" { //第一次查询,默认展示最新得成交记录
values, err = localdb.List(prefix, nil, count, direction) rows, err = query.ListIndex("index", prefix, nil, count, direction)
} else { } else {
values, err = localdb.List(prefix, key, count, direction) rows, err = query.ListIndex("index", prefix, []byte(primaryKey), count, direction)
} }
if err != nil { if err != nil {
elog.Error("QueryOrderList.", "addr", addr, "err", err.Error())
return nil, err return nil, err
} }
var list []*et.OrderID
for _, value := range values {
var orderID et.OrderID
err := types.Decode(value, &orderID)
if err != nil {
elog.Warn("QueryOrderList.Decode", "marketDept", "err", err.Error())
continue
}
list = append(list, &orderID)
}
var orderList et.OrderList var orderList et.OrderList
for _, orderID := range list { for _, row := range rows {
order, err := findOrderByOrderID(statedb, orderID.ID) order := row.Data.(*et.Order)
if err != nil {
continue
}
//替换索引index
order.Index = orderID.Index
//替换已经成交得量 //替换已经成交得量
order.Executed = order.GetLimitOrder().Amount - order.Balance order.Executed = order.GetLimitOrder().Amount - order.Balance
orderList.List = append(orderList.List, order) orderList.List = append(orderList.List, order)
} }
//设置主键索引
if len(rows) == int(count) {
orderList.PrimaryKey = string(rows[len(rows)-1].Primary)
}
return &orderList, nil return &orderList, nil
} }
func queryMarketDepth(localdb dbm.KVDB, left, right *et.Asset, op int32, price float64) (*et.MarketDepth, error) {
table := NewMarketDepthTable(localdb)
primaryKey := []byte(fmt.Sprintf("%s:%s:%d:%016d", left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float64(1e8))))
row, err := table.GetData(primaryKey)
if err != nil {
return nil, err
}
return row.Data.(*et.MarketDepth), nil
}
//截取小数点后8位 //截取小数点后8位
func Truncate(price float64) float64 { func Truncate(price float64) float64 {
return math.Trunc(float64(1e8)*price) / float64(1e8) return math.Trunc(float64(1e8)*price) / float64(1e8)
......
...@@ -2,7 +2,7 @@ package executor ...@@ -2,7 +2,7 @@ package executor
import ( import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
exchangetypes "github.com/33cn/plugin/plugin/dapp/exchange/types" ety "github.com/33cn/plugin/plugin/dapp/exchange/types"
) )
/* /*
...@@ -10,13 +10,13 @@ import ( ...@@ -10,13 +10,13 @@ import (
* 非关键数据,本地存储(localDB), 用于辅助查询,效率高 * 非关键数据,本地存储(localDB), 用于辅助查询,效率高
*/ */
func (e *exchange) ExecLocal_LimitOrder(payload *exchangetypes.LimitOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (e *exchange) ExecLocal_LimitOrder(payload *ety.LimitOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{} dbSet := &types.LocalDBSet{}
if receiptData.Ty == types.ExecOk { if receiptData.Ty == types.ExecOk {
for _, log := range receiptData.Logs { for _, log := range receiptData.Logs {
switch log.Ty { switch log.Ty {
case exchangetypes.TyLimitOrderLog: case ety.TyLimitOrderLog:
receipt := &exchangetypes.ReceiptExchange{} receipt := &ety.ReceiptExchange{}
if err := types.Decode(log.Log, receipt); err != nil { if err := types.Decode(log.Log, receipt); err != nil {
return nil, err return nil, err
} }
...@@ -28,13 +28,13 @@ func (e *exchange) ExecLocal_LimitOrder(payload *exchangetypes.LimitOrder, tx *t ...@@ -28,13 +28,13 @@ func (e *exchange) ExecLocal_LimitOrder(payload *exchangetypes.LimitOrder, tx *t
return e.addAutoRollBack(tx, dbSet.KV), nil return e.addAutoRollBack(tx, dbSet.KV), nil
} }
func (e *exchange) ExecLocal_MarketOrder(payload *exchangetypes.MarketOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (e *exchange) ExecLocal_MarketOrder(payload *ety.MarketOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{} dbSet := &types.LocalDBSet{}
if receiptData.Ty == types.ExecOk { if receiptData.Ty == types.ExecOk {
for _, log := range receiptData.Logs { for _, log := range receiptData.Logs {
switch log.Ty { switch log.Ty {
case exchangetypes.TyMarketOrderLog: case ety.TyMarketOrderLog:
receipt := &exchangetypes.ReceiptExchange{} receipt := &ety.ReceiptExchange{}
if err := types.Decode(log.Log, receipt); err != nil { if err := types.Decode(log.Log, receipt); err != nil {
return nil, err return nil, err
} }
...@@ -46,13 +46,13 @@ func (e *exchange) ExecLocal_MarketOrder(payload *exchangetypes.MarketOrder, tx ...@@ -46,13 +46,13 @@ func (e *exchange) ExecLocal_MarketOrder(payload *exchangetypes.MarketOrder, tx
return e.addAutoRollBack(tx, dbSet.KV), nil return e.addAutoRollBack(tx, dbSet.KV), nil
} }
func (e *exchange) ExecLocal_RevokeOrder(payload *exchangetypes.RevokeOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (e *exchange) ExecLocal_RevokeOrder(payload *ety.RevokeOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{} dbSet := &types.LocalDBSet{}
if receiptData.Ty == types.ExecOk { if receiptData.Ty == types.ExecOk {
for _, log := range receiptData.Logs { for _, log := range receiptData.Logs {
switch log.Ty { switch log.Ty {
case exchangetypes.TyRevokeOrderLog: case ety.TyRevokeOrderLog:
receipt := &exchangetypes.ReceiptExchange{} receipt := &ety.ReceiptExchange{}
if err := types.Decode(log.Log, receipt); err != nil { if err := types.Decode(log.Log, receipt); err != nil {
return nil, err return nil, err
} }
...@@ -72,18 +72,21 @@ func (e *exchange) addAutoRollBack(tx *types.Transaction, kv []*types.KeyValue) ...@@ -72,18 +72,21 @@ func (e *exchange) addAutoRollBack(tx *types.Transaction, kv []*types.KeyValue)
return dbSet return dbSet
} }
func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*types.KeyValue) { func (e *exchange) updateIndex(receipt *ety.ReceiptExchange) (kvs []*types.KeyValue) {
completedTable := NewCompletedOrderTable(e.GetLocalDB())
marketTable := NewMarketDepthTable(e.GetLocalDB())
userTable := NewUserOrderTable(e.GetLocalDB())
orderTable := NewMarketOrderTable(e.GetLocalDB())
switch receipt.Order.Status { switch receipt.Order.Status {
case exchangetypes.Ordered: case ety.Ordered:
left := receipt.GetOrder().GetLimitOrder().GetLeftAsset() left := receipt.GetOrder().GetLimitOrder().GetLeftAsset()
right := receipt.GetOrder().GetLimitOrder().GetRightAsset() right := receipt.GetOrder().GetLimitOrder().GetRightAsset()
op := receipt.GetOrder().GetLimitOrder().GetOp() op := receipt.GetOrder().GetLimitOrder().GetOp()
price := receipt.GetOrder().GetLimitOrder().GetPrice() price := receipt.GetOrder().GetLimitOrder().GetPrice()
oderID := receipt.GetOrder().OrderID order := receipt.GetOrder()
index := receipt.GetIndex() index := receipt.GetIndex()
addr := receipt.GetOrder().Addr var markDepth ety.MarketDepth
var markDepth exchangetypes.MarketDepth depth, err := queryMarketDepth(e.GetLocalDB(), left, right, op, price)
err := findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, op, price), &markDepth)
if err == types.ErrNotFound { if err == types.ErrNotFound {
markDepth.Price = price markDepth.Price = price
markDepth.LeftAsset = left markDepth.LeftAsset = left
...@@ -95,38 +98,61 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -95,38 +98,61 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
markDepth.LeftAsset = left markDepth.LeftAsset = left
markDepth.RightAsset = right markDepth.RightAsset = right
markDepth.Op = op markDepth.Op = op
markDepth.Amount = markDepth.Amount + receipt.Order.Balance markDepth.Amount = depth.Amount + receipt.Order.Balance
} }
//marketDepth //marketDepth
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, op, price), Value: types.Encode(&markDepth)}) err = marketTable.Replace(&markDepth)
//orderID if err != nil {
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, op, price, receipt.Index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})}) elog.Error("updateIndex", "marketTable.Replace", err.Error())
//addr orderID return nil
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})}) }
err = orderTable.Replace(order)
if err != nil {
elog.Error("updateIndex", "orderTable.Replace", err.Error())
return nil
}
err = userTable.Replace(order)
if err != nil {
return nil
}
if len(receipt.MatchOrders) > 0 { if len(receipt.MatchOrders) > 0 {
//撮合交易更新 //撮合交易更新
cache := make(map[float64]int64) cache := make(map[float64]int64)
for i, matchOrder := range receipt.MatchOrders { for i, matchOrder := range receipt.MatchOrders {
if matchOrder.Status == exchangetypes.Completed { if matchOrder.Status == ety.Completed {
// 删除原有状态orderID // 删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, matchOrder.GetLimitOrder().Op, matchOrder.GetLimitOrder().Price, matchOrder.Index), Value: nil}) err = orderTable.DelRow(matchOrder)
if err != nil {
elog.Error("updateIndex", "orderTable.DelRow", err.Error())
return nil
}
//删除原有状态orderID //删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, matchOrder.Addr, matchOrder.Index), Value: nil}) matchOrder.Status = ety.Ordered
userTable.DelRow(matchOrder)
//更新状态为已完成,索引index,改为当前的index //更新状态为已完成,索引index,改为当前的index
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Completed, matchOrder.Addr, index+int64(i+1)), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, Index: index + int64(i+1)})}) matchOrder.Status = ety.Completed
matchOrder.Index = index + int64(i+1)
userTable.Replace(matchOrder)
//calcCompletedOrderKey //calcCompletedOrderKey
kvs = append(kvs, &types.KeyValue{Key: calcCompletedOrderKey(left, right, index+int64(i+1)), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, Index: index + int64(i+1)})}) completedTable.Replace(matchOrder)
}
if matchOrder.Status == ety.Ordered {
//更新数据
err = orderTable.Replace(matchOrder)
if err != nil {
elog.Error("updateIndex", "orderTable.Replace", err.Error())
return nil
}
} }
executed := cache[matchOrder.GetLimitOrder().Price] executed := cache[matchOrder.GetLimitOrder().Price]
executed = executed + matchOrder.Executed executed = executed + matchOrder.Executed
cache[matchOrder.GetLimitOrder().Price] = executed cache[matchOrder.GetLimitOrder().Price] = executed
} }
//更改匹配市场深度 //更改匹配市场深度
for pr, executed := range cache { for pr, executed := range cache {
var matchDepth exchangetypes.MarketDepth var matchDepth ety.MarketDepth
err = findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), pr), &matchDepth) depth, err := queryMarketDepth(e.GetLocalDB(), left, right, OpSwap(op), pr)
if err == types.ErrNotFound { if err == types.ErrNotFound {
continue continue
} else { } else {
...@@ -134,46 +160,80 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -134,46 +160,80 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
matchDepth.LeftAsset = left matchDepth.LeftAsset = left
matchDepth.RightAsset = right matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op) matchDepth.Op = OpSwap(op)
matchDepth.Amount = matchDepth.Amount - executed matchDepth.Amount = depth.Amount - executed
} }
//marketDepth //marketDepth
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: types.Encode(&matchDepth)}) err = marketTable.Replace(&matchDepth)
if err != nil {
elog.Error("updateIndex", "marketTable.Replace", err.Error())
return nil
}
if matchDepth.Amount <= 0 { if matchDepth.Amount <= 0 {
//删除 //删除
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: nil}) err = marketTable.DelRow(&matchDepth)
if err != nil {
elog.Error("updateIndex", "marketTable.DelRow", err.Error())
return nil
}
} }
} }
} }
return case ety.Completed:
case exchangetypes.Completed:
left := receipt.GetOrder().GetLimitOrder().GetLeftAsset() left := receipt.GetOrder().GetLimitOrder().GetLeftAsset()
right := receipt.GetOrder().GetLimitOrder().GetRightAsset() right := receipt.GetOrder().GetLimitOrder().GetRightAsset()
op := receipt.GetOrder().GetLimitOrder().GetOp() op := receipt.GetOrder().GetLimitOrder().GetOp()
price := receipt.GetOrder().GetLimitOrder().GetPrice()
oderID := receipt.GetOrder().OrderID
index := receipt.GetIndex() index := receipt.GetIndex()
addr := receipt.GetOrder().Addr err := userTable.Replace(receipt.GetOrder())
if err != nil {
//user orderID elog.Error("updateIndex", "userTable.Replace", err.Error())
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Completed, addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})}) return nil
}
//calcCompletedOrderKey err = completedTable.Replace(receipt.Order)
kvs = append(kvs, &types.KeyValue{Key: calcCompletedOrderKey(left, right, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})}) if err != nil {
elog.Error("updateIndex", "completedTable.Replace", err.Error())
return nil
}
cache := make(map[float64]int64) cache := make(map[float64]int64)
if len(receipt.MatchOrders) > 0 { if len(receipt.MatchOrders) > 0 {
//撮合交易更新 //撮合交易更新
for i, matchOrder := range receipt.MatchOrders { for i, matchOrder := range receipt.MatchOrders {
if matchOrder.Status == exchangetypes.Completed { if matchOrder.Status == ety.Completed {
// 删除原有状态orderID // 删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, matchOrder.GetLimitOrder().Op, price, matchOrder.Index), Value: nil}) err = orderTable.DelRow(matchOrder)
if err != nil {
elog.Error("updateIndex", "orderTable.DelRow", err.Error())
return nil
}
//删除原有状态orderID //删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, matchOrder.Addr, matchOrder.Index), Value: nil}) matchOrder.Status = ety.Ordered
err = userTable.DelRow(matchOrder)
if err != nil {
elog.Error("updateIndex", "userTable.DelRow", err.Error())
return nil
}
//更新状态为已完成,更新索引 //更新状态为已完成,更新索引
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Completed, matchOrder.Addr, index+int64(i+1)), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, Index: index + int64(i+1)})}) matchOrder.Status = ety.Completed
matchOrder.Index = index + int64(i+1)
err = userTable.Replace(matchOrder)
if err != nil {
elog.Error("updateIndex", "userTable.Replace", err.Error())
return nil
}
//calcCompletedOrderKey //calcCompletedOrderKey
kvs = append(kvs, &types.KeyValue{Key: calcCompletedOrderKey(left, right, index+int64(i+1)), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, Index: index + int64(i+1)})}) err = completedTable.Replace(matchOrder)
if err != nil {
elog.Error("updateIndex", "completedTable.Replace", err.Error())
return nil
}
}
if matchOrder.Status == ety.Ordered {
//更新数据
err = orderTable.Replace(matchOrder)
if err != nil {
elog.Error("updateIndex", "orderTable.Replace", err.Error())
return nil
}
} }
executed := cache[matchOrder.GetLimitOrder().Price] executed := cache[matchOrder.GetLimitOrder().Price]
executed = executed + matchOrder.Executed executed = executed + matchOrder.Executed
...@@ -181,8 +241,8 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -181,8 +241,8 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
} }
//更改match市场深度 //更改match市场深度
for pr, executed := range cache { for pr, executed := range cache {
var matchDepth exchangetypes.MarketDepth var matchDepth ety.MarketDepth
err := findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), pr), &matchDepth) depth, err := queryMarketDepth(e.GetLocalDB(), left, right, OpSwap(op), pr)
if err == types.ErrNotFound { if err == types.ErrNotFound {
continue continue
} else { } else {
...@@ -190,51 +250,105 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -190,51 +250,105 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
matchDepth.LeftAsset = left matchDepth.LeftAsset = left
matchDepth.RightAsset = right matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op) matchDepth.Op = OpSwap(op)
matchDepth.Amount = matchDepth.Amount - executed matchDepth.Amount = depth.Amount - executed
} }
//marketDepth //marketDepth
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: types.Encode(&matchDepth)}) err = marketTable.Replace(&matchDepth)
if err != nil {
elog.Error("updateIndex", "marketTable.Replace", err.Error())
return nil
}
if matchDepth.Amount <= 0 { if matchDepth.Amount <= 0 {
//删除 //删除
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: nil}) err = marketTable.DelRow(&matchDepth)
if err != nil {
elog.Error("updateIndex", "marketTable.DelRow", err.Error())
return nil
}
} }
} }
} }
return case ety.Revoked:
case exchangetypes.Revoked:
//只有状态时ordered状态的订单才能被撤回 //只有状态时ordered状态的订单才能被撤回
left := receipt.GetOrder().GetLimitOrder().GetLeftAsset() left := receipt.GetOrder().GetLimitOrder().GetLeftAsset()
right := receipt.GetOrder().GetLimitOrder().GetRightAsset() right := receipt.GetOrder().GetLimitOrder().GetRightAsset()
op := receipt.GetOrder().GetLimitOrder().GetOp() op := receipt.GetOrder().GetLimitOrder().GetOp()
price := receipt.GetOrder().GetLimitOrder().GetPrice() price := receipt.GetOrder().GetLimitOrder().GetPrice()
oderID := receipt.GetOrder().OrderID order := receipt.GetOrder()
index := receipt.GetIndex() index := receipt.GetIndex()
addr := receipt.GetOrder().Addr var marketDepth ety.MarketDepth
var marketDepth exchangetypes.MarketDepth depth, err := queryMarketDepth(e.GetLocalDB(), left, right, op, price)
err := findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, op, price), &marketDepth)
if err == nil { if err == nil {
//marketDepth //marketDepth
marketDepth.Amount = marketDepth.Amount - receipt.GetOrder().Balance marketDepth.Amount = depth.Amount - receipt.GetOrder().Balance
elog.Error("revoked", "recept.order.balance", receipt.GetOrder().Balance) err = marketTable.Replace(&marketDepth)
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, op, price), Value: types.Encode(&marketDepth)}) if err != nil {
elog.Error("updateIndex", "marketTable.Replace", err.Error())
return nil
}
} }
elog.Error("revoked", "marketDepth.Amount", marketDepth.Amount)
if marketDepth.Amount == 0 { if marketDepth.Amount == 0 {
//删除 //删除
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, op, price), Value: nil}) err = marketTable.DelRow(&marketDepth)
if err != nil {
elog.Error("updateIndex", "marketTable.DelRow", err.Error())
return nil
}
} }
// 删除原有状态orderID // 删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, op, price, receipt.GetOrder().Index), Value: nil}) err = orderTable.DelRow(order)
if err != nil {
elog.Error("updateIndex", "orderTable.DelRow", err.Error())
return nil
}
//删除原有状态orderID //删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, addr, receipt.GetOrder().Index), Value: nil}) order.Status = ety.Ordered
err = userTable.DelRow(order)
if err != nil {
elog.Error("updateIndex", "userTable.DelRow", err.Error())
return nil
}
order.Status = ety.Revoked
order.Index = index
//添加撤销的订单 //添加撤销的订单
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Revoked, addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})}) err = userTable.Replace(order)
if err != nil {
elog.Error("updateIndex", "userTable.Replace", err.Error())
return nil
}
} }
kv, err := marketTable.Save()
if err != nil {
elog.Error("updateIndex", "marketTable.Save", err.Error())
return nil
}
kvs = append(kvs, kv...)
kv, err = userTable.Save()
if err != nil {
elog.Error("updateIndex", "userTable.Save", err.Error())
return nil
}
kvs = append(kvs, kv...)
kv, err = orderTable.Save()
if err != nil {
elog.Error("updateIndex", "orderTable.Save", err.Error())
return nil
}
kvs = append(kvs, kv...)
kv, err = completedTable.Save()
if err != nil {
elog.Error("updateIndex", "completedTable.Save", err.Error())
return nil
}
kvs = append(kvs, kv...)
return return
} }
func OpSwap(op int32) int32 { func OpSwap(op int32) int32 {
if op == exchangetypes.OpBuy { if op == ety.OpBuy {
return exchangetypes.OpSell return ety.OpSell
} }
return exchangetypes.OpBuy return ety.OpBuy
} }
package executor
import (
"fmt"
"github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
* 用户合约存取kv数据时,key值前缀需要满足一定规范
* 即key = keyPrefix + userKey
* 需要字段前缀查询时,使用’-‘作为分割符号
*/
var (
//KeyPrefixStateDB state db key必须前缀
KeyPrefixStateDB = "mavl-exchange-"
//KeyPrefixLocalDB local db的key必须前缀
KeyPrefixLocalDB = "LODB-exchange-"
)
//状态数据库中存储具体挂单信息
func calcOrderKey(orderID string) []byte {
key := fmt.Sprintf("%s"+"orderID:%s", KeyPrefixStateDB, orderID)
return []byte(key)
}
func calcMarketDepthPrefix(left, right *types.Asset, op int32) []byte {
key := fmt.Sprintf("%s"+"depth-%s-%s-%d:", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op)
return []byte(key)
}
//市场深度
func calcMarketDepthKey(left, right *types.Asset, op int32, price float64) []byte {
// 设置精度为1e8
key := fmt.Sprintf("%s"+"depth-%s-%s-%d:%016d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float64(1e8)))
return []byte(key)
}
func calcMarketDepthOrderPrefix(left, right *types.Asset, op int32, price float64) []byte {
// 设置精度为1e8
key := fmt.Sprintf("%s"+"order-%s-%s-%d:%016d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float64(1e8)))
return []byte(key)
}
// localdb中存储市场挂单ID
func calcMarketDepthOrderKey(left, right *types.Asset, op int32, price float64, index int64) []byte {
// 设置精度为1e8
key := fmt.Sprintf("%s"+"order-%s-%s-%d:%016d:%022d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float64(1e8)), index)
return []byte(key)
}
//最新已经成交的订单,这里状态固定都是完成状态,这个主要给外部使用,可以查询最新得成交信息,存在多个情况
//matchOrderIndex,是匹配order在数组中的index,这里预留4个0000,用来解决同一笔交易中存在key重复得情况,这样设计保证了key得唯一性
func calcCompletedOrderKey(left, right *types.Asset, index int64) []byte {
// 设置精度为1e8
key := fmt.Sprintf("%s"+"completed-%s-%s-%d:%022d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), types.Completed, index)
return []byte(key)
}
func calcCompletedOrderPrefix(left, right *types.Asset) []byte {
// 设置精度为1e8
key := fmt.Sprintf("%s"+"completed-%s-%s-%d:", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), types.Completed)
return []byte(key)
}
//根据地址和订单状态,去查询订单列表,包含所有交易对
func calcUserOrderIDPrefix(status int32, addr string) []byte {
key := fmt.Sprintf("%s"+"addr:%s:%d:", KeyPrefixLocalDB, addr, status)
return []byte(key)
}
//matchOrderIndex,用来解决同一笔交易中存在key重复得情况,这样设计保证了key得唯一性
func calcUserOrderIDKey(status int32, addr string, index int64) []byte {
key := fmt.Sprintf("%s"+"addr:%s:%d:%022d", KeyPrefixLocalDB, addr, status, index)
return []byte(key)
}
...@@ -20,7 +20,7 @@ func (s *exchange) Query_QueryMarketDepth(in *et.QueryMarketDepth) (types.Messag ...@@ -20,7 +20,7 @@ func (s *exchange) Query_QueryMarketDepth(in *et.QueryMarketDepth) (types.Messag
if !CheckOp(in.Op) { if !CheckOp(in.Op) {
return nil, et.ErrAssetOp return nil, et.ErrAssetOp
} }
return QueryMarketDepth(s.GetLocalDB(), in.LeftAsset, in.RightAsset, in.Op, in.Price, in.Count) return QueryMarketDepth(s.GetLocalDB(), in.LeftAsset, in.RightAsset, in.Op, in.PrimaryKey, in.Count)
} }
//查询已经完成得订单 //查询已经完成得订单
...@@ -35,15 +35,15 @@ func (s *exchange) Query_QueryCompletedOrderList(in *et.QueryCompletedOrderList) ...@@ -35,15 +35,15 @@ func (s *exchange) Query_QueryCompletedOrderList(in *et.QueryCompletedOrderList)
if !CheckDirection(in.Direction) { if !CheckDirection(in.Direction) {
return nil, et.ErrDirection return nil, et.ErrDirection
} }
return QueryCompletedOrderList(s.GetLocalDB(), s.GetStateDB(), in.LeftAsset, in.RightAsset, in.Index, in.Count, in.Direction) return QueryCompletedOrderList(s.GetLocalDB(), in.LeftAsset, in.RightAsset, in.PrimaryKey, in.Count, in.Direction)
} }
//根据orderID查询订单信息 //根据orderID查询订单信息
func (s *exchange) Query_QueryOrder(in *et.QueryOrder) (types.Message, error) { func (s *exchange) Query_QueryOrder(in *et.QueryOrder) (types.Message, error) {
if in.OrderID == "" { if in.OrderID == 0 {
return nil, et.ErrOrderID return nil, et.ErrOrderID
} }
return findOrderByOrderID(s.GetStateDB(), in.OrderID) return findOrderByOrderID(s.GetStateDB(), s.GetLocalDB(), in.OrderID)
} }
//根据订单状态,查询订单信息(这里面包含所有交易对) //根据订单状态,查询订单信息(这里面包含所有交易对)
...@@ -62,5 +62,5 @@ func (s *exchange) Query_QueryOrderList(in *et.QueryOrderList) (types.Message, e ...@@ -62,5 +62,5 @@ func (s *exchange) Query_QueryOrderList(in *et.QueryOrderList) (types.Message, e
if in.Address == "" { if in.Address == "" {
return nil, et.ErrAddr return nil, et.ErrAddr
} }
return QueryOrderList(s.GetLocalDB(), s.GetStateDB(), in.Address, in.Status, in.Count, in.Direction, in.Index) return QueryOrderList(s.GetLocalDB(), s.GetStateDB(), in.Address, in.Status, in.Count, in.Direction, in.PrimaryKey)
} }
package executor
import (
"fmt"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
ety "github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
* 用户合约存取kv数据时,key值前缀需要满足一定规范
* 即key = keyPrefix + userKey
* 需要字段前缀查询时,使用’-‘作为分割符号
*/
const (
//KeyPrefixStateDB state db key必须前缀
KeyPrefixStateDB = "mavl-exchange-"
//KeyPrefixLocalDB local db的key必须前缀
KeyPrefixLocalDB = "LODB-exchange"
)
//状态数据库中存储具体挂单信息
func calcOrderKey(orderID int64) []byte {
key := fmt.Sprintf("%s"+"orderID:%022d", KeyPrefixStateDB, orderID)
return []byte(key)
}
var opt_exchange_depth = &table.Option{
Prefix: KeyPrefixLocalDB,
Name: "depth",
Primary: "price",
Index: nil,
}
//重新设计表,list查询全部在订单信息localdb查询中
var opt_exchange_order = &table.Option{
Prefix: KeyPrefixLocalDB,
Name: "order",
Primary: "orderID",
Index: []string{"market_order"},
}
//根据地址和状态,index是实时在变化,要有先后顺序
var opt_exchange_user_order = &table.Option{
Prefix: KeyPrefixLocalDB,
Name: "UserOrder",
Primary: "index",
Index: nil,
}
var opt_exchange_completed = &table.Option{
Prefix: KeyPrefixLocalDB,
Name: "completed",
Primary: "index",
Index: nil,
}
//NewTable 新建表
func NewMarketDepthTable(kvdb db.KV) *table.Table {
rowmeta := NewMarketDepthRow()
table, err := table.NewTable(rowmeta, kvdb, opt_exchange_depth)
if err != nil {
panic(err)
}
return table
}
func NewMarketOrderTable(kvdb db.KV) *table.Table {
rowmeta := NewOrderRow()
table, err := table.NewTable(rowmeta, kvdb, opt_exchange_order)
if err != nil {
panic(err)
}
return table
}
func NewUserOrderTable(kvdb db.KV) *table.Table {
rowmeta := NewUserOrderRow()
table, err := table.NewTable(rowmeta, kvdb, opt_exchange_user_order)
if err != nil {
panic(err)
}
return table
}
func NewCompletedOrderTable(kvdb db.KV) *table.Table {
rowmeta := NewCompletedOrderRow()
table, err := table.NewTable(rowmeta, kvdb, opt_exchange_completed)
if err != nil {
panic(err)
}
return table
}
//OrderRow table meta 结构
type OrderRow struct {
*ety.Order
}
//NewOrderRow 新建一个meta 结构
func NewOrderRow() *OrderRow {
return &OrderRow{Order: &ety.Order{}}
}
//CreateRow
func (r *OrderRow) CreateRow() *table.Row {
return &table.Row{Data: &ety.Order{}}
}
//SetPayload 设置数据
func (r *OrderRow) SetPayload(data types.Message) error {
if txdata, ok := data.(*ety.Order); ok {
r.Order = txdata
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (r *OrderRow) Get(key string) ([]byte, error) {
if key == "orderID" {
return []byte(fmt.Sprintf("%022d",r.OrderID)), nil
}else if key == "market_order"{
return []byte(fmt.Sprintf("%s:%s:%d:%016d", r.GetLimitOrder().LeftAsset.GetSymbol(), r.GetLimitOrder().RightAsset.GetSymbol(), r.GetLimitOrder().Op, int64(Truncate(r.GetLimitOrder().Price*float64(1e8))))), nil
}
return nil, types.ErrNotFound
}
//UserOrderRow table meta 结构
type UserOrderRow struct {
*ety.Order
}
//NewOrderRow 新建一个meta 结构
func NewUserOrderRow() *UserOrderRow {
return &UserOrderRow{Order: &ety.Order{Value: &ety.Order_LimitOrder{LimitOrder: &ety.LimitOrder{}}}}
}
//CreateRow
func (r *UserOrderRow) CreateRow() *table.Row {
return &table.Row{Data: &ety.Order{}}
}
//SetPayload 设置数据
func (r *UserOrderRow) SetPayload(data types.Message) error {
if txdata, ok := data.(*ety.Order); ok {
r.Order = txdata
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (r *UserOrderRow) Get(key string) ([]byte, error) {
if key == "index" {
return []byte(fmt.Sprintf("%s:%d:%022d", r.Addr, r.Status, r.Index)), nil
}
return nil, types.ErrNotFound
}
//CompletedOrderRow table meta 结构
type CompletedOrderRow struct {
*ety.Order
}
func NewCompletedOrderRow() *CompletedOrderRow {
return &CompletedOrderRow{Order: &ety.Order{Value: &ety.Order_LimitOrder{LimitOrder: &ety.LimitOrder{}}}}
}
func (m *CompletedOrderRow) CreateRow() *table.Row {
return &table.Row{Data: &ety.Order{Value: &ety.Order_LimitOrder{LimitOrder: &ety.LimitOrder{}}}}
}
//SetPayload 设置数据
func (m *CompletedOrderRow) SetPayload(data types.Message) error {
if txdata, ok := data.(*ety.Order); ok {
m.Order = txdata
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (m *CompletedOrderRow) Get(key string) ([]byte, error) {
if key == "index" {
return []byte(fmt.Sprintf("%s:%s:%022d", m.GetLimitOrder().LeftAsset.GetSymbol(), m.GetLimitOrder().RightAsset.GetSymbol(), m.Index)), nil
}
return nil, types.ErrNotFound
}
//marketDepthRow table meta 结构
type MarketDepthRow struct {
*ety.MarketDepth
}
//NewOracleRow 新建一个meta 结构
func NewMarketDepthRow() *MarketDepthRow {
return &MarketDepthRow{MarketDepth: &ety.MarketDepth{}}
}
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存eventid)
func (m *MarketDepthRow) CreateRow() *table.Row {
return &table.Row{Data: &ety.MarketDepth{}}
}
//SetPayload 设置数据
func (m *MarketDepthRow) SetPayload(data types.Message) error {
if txdata, ok := data.(*ety.MarketDepth); ok {
m.MarketDepth = txdata
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (m *MarketDepthRow) Get(key string) ([]byte, error) {
if key == "price" {
return []byte(fmt.Sprintf("%s:%s:%d:%016d", m.LeftAsset.GetSymbol(), m.RightAsset.GetSymbol(), m.Op, int64(Truncate(m.Price)*float64(1e8)))), nil
}
return nil, types.ErrNotFound
}
...@@ -41,7 +41,7 @@ message MarketOrder { ...@@ -41,7 +41,7 @@ message MarketOrder {
//撤回订单 //撤回订单
message RevokeOrder { message RevokeOrder {
//订单号 //订单号
string orderID = 1; int64 orderID = 1;
} }
//资产类型 //资产类型
message asset { message asset {
...@@ -51,7 +51,7 @@ message asset { ...@@ -51,7 +51,7 @@ message asset {
//订单信息 //订单信息
message Order { message Order {
string orderID = 1; int64 orderID = 1;
oneof value { oneof value {
LimitOrder limitOrder = 2; LimitOrder limitOrder = 2;
MarketOrder marketOrder = 3; MarketOrder marketOrder = 3;
...@@ -72,16 +72,6 @@ message Order { ...@@ -72,16 +72,6 @@ message Order {
int64 index = 10; int64 index = 10;
} }
//挂单价
message OrderPrice {
double price = 1;
int64 index = 2;
}
//单号
message OrderID {
string ID = 1;
int64 index = 2;
}
//查询接口 //查询接口
message QueryMarketDepth { message QueryMarketDepth {
//资产1 //资产1
...@@ -91,7 +81,7 @@ message QueryMarketDepth { ...@@ -91,7 +81,7 @@ message QueryMarketDepth {
//操作, 1为买,2为卖 //操作, 1为买,2为卖
int32 op = 3; int32 op = 3;
// 这里用价格作为索引值 // 这里用价格作为索引值
double price = 4; string primaryKey = 4;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 //单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 5; int32 count = 5;
} }
...@@ -111,6 +101,7 @@ message MarketDepth { ...@@ -111,6 +101,7 @@ message MarketDepth {
//查询接口返回的市场深度列表 //查询接口返回的市场深度列表
message MarketDepthList { message MarketDepthList {
repeated MarketDepth list = 1; repeated MarketDepth list = 1;
string primaryKey = 2;
} }
//查询最新得成交信息,外部接口 //查询最新得成交信息,外部接口
...@@ -120,7 +111,7 @@ message QueryCompletedOrderList { ...@@ -120,7 +111,7 @@ message QueryCompletedOrderList {
//资产2 //资产2
asset rightAsset = 2; asset rightAsset = 2;
// 索引值 // 索引值
int64 index = 3; string primaryKey = 3;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 //单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 4; int32 count = 4;
// 0降序,1升序,默认降序 // 0降序,1升序,默认降序
...@@ -129,7 +120,7 @@ message QueryCompletedOrderList { ...@@ -129,7 +120,7 @@ message QueryCompletedOrderList {
//根据orderID去查询订单信息 //根据orderID去查询订单信息
message QueryOrder { message QueryOrder {
string orderID = 1; int64 orderID = 1;
} }
//根据地址,状态查询用户自己的挂单信息 //根据地址,状态查询用户自己的挂单信息
message QueryOrderList { message QueryOrderList {
...@@ -137,8 +128,8 @@ message QueryOrderList { ...@@ -137,8 +128,8 @@ message QueryOrderList {
int32 status = 1; int32 status = 1;
//用户地址信息,必填 //用户地址信息,必填
string address = 2; string address = 2;
// 索引值 // 主键索引
int64 index = 3; string primaryKey = 3;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 //单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 4; int32 count = 4;
// 0降序,1升序,默认降序 // 0降序,1升序,默认降序
...@@ -147,6 +138,7 @@ message QueryOrderList { ...@@ -147,6 +138,7 @@ message QueryOrderList {
//订单列表 //订单列表
message OrderList { message OrderList {
repeated Order list = 1; repeated Order list = 1;
string primaryKey = 2;
} }
......
...@@ -2,6 +2,7 @@ package types ...@@ -2,6 +2,7 @@ package types
import ( import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"reflect"
) )
/* /*
...@@ -73,7 +74,9 @@ var ( ...@@ -73,7 +74,9 @@ var (
} }
//定义log的id和具体log类型及名称,填入具体自定义log类型 //定义log的id和具体log类型及名称,填入具体自定义log类型
logMap = map[int64]*types.LogInfo{ logMap = map[int64]*types.LogInfo{
//LogID: {Ty: reflect.TypeOf(LogStruct), Name: LogName}, TyLimitOrderLog: {Ty: reflect.TypeOf(ReceiptExchange{}), Name: "TyLimitOrderLog"},
TyMarketOrderLog: {Ty: reflect.TypeOf(ReceiptExchange{}), Name: "TyMarketOrderLog"},
TyRevokeOrderLog: {Ty: reflect.TypeOf(ReceiptExchange{}), Name: "TyRevokeOrderLog"},
} }
//tlog = log.New("module", "exchange.types") //tlog = log.New("module", "exchange.types")
) )
......
...@@ -15,8 +15,6 @@ It has these top-level messages: ...@@ -15,8 +15,6 @@ It has these top-level messages:
RevokeOrder RevokeOrder
Asset Asset
Order Order
OrderPrice
OrderID
QueryMarketDepth QueryMarketDepth
MarketDepth MarketDepth
MarketDepthList MarketDepthList
...@@ -28,15 +26,12 @@ It has these top-level messages: ...@@ -28,15 +26,12 @@ It has these top-level messages:
*/ */
package types package types
import ( import proto "github.com/golang/protobuf/proto"
fmt "fmt" import fmt "fmt"
import math "math"
proto "github.com/golang/protobuf/proto"
math "math"
import (
context "golang.org/x/net/context" context "golang.org/x/net/context"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
) )
...@@ -321,7 +316,7 @@ func (m *MarketOrder) GetOp() int32 { ...@@ -321,7 +316,7 @@ func (m *MarketOrder) GetOp() int32 {
// 撤回订单 // 撤回订单
type RevokeOrder struct { type RevokeOrder struct {
// 订单号 // 订单号
OrderID string `protobuf:"bytes,1,opt,name=orderID" json:"orderID,omitempty"` OrderID int64 `protobuf:"varint,1,opt,name=orderID" json:"orderID,omitempty"`
} }
func (m *RevokeOrder) Reset() { *m = RevokeOrder{} } func (m *RevokeOrder) Reset() { *m = RevokeOrder{} }
...@@ -329,11 +324,11 @@ func (m *RevokeOrder) String() string { return proto.CompactTextStrin ...@@ -329,11 +324,11 @@ func (m *RevokeOrder) String() string { return proto.CompactTextStrin
func (*RevokeOrder) ProtoMessage() {} func (*RevokeOrder) ProtoMessage() {}
func (*RevokeOrder) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } func (*RevokeOrder) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *RevokeOrder) GetOrderID() string { func (m *RevokeOrder) GetOrderID() int64 {
if m != nil { if m != nil {
return m.OrderID return m.OrderID
} }
return "" return 0
} }
// 资产类型 // 资产类型
...@@ -363,7 +358,7 @@ func (m *Asset) GetSymbol() string { ...@@ -363,7 +358,7 @@ func (m *Asset) GetSymbol() string {
// 订单信息 // 订单信息
type Order struct { type Order struct {
OrderID string `protobuf:"bytes,1,opt,name=orderID" json:"orderID,omitempty"` OrderID int64 `protobuf:"varint,1,opt,name=orderID" json:"orderID,omitempty"`
// Types that are valid to be assigned to Value: // Types that are valid to be assigned to Value:
// *Order_LimitOrder // *Order_LimitOrder
// *Order_MarketOrder // *Order_MarketOrder
...@@ -410,11 +405,11 @@ func (m *Order) GetValue() isOrder_Value { ...@@ -410,11 +405,11 @@ func (m *Order) GetValue() isOrder_Value {
return nil return nil
} }
func (m *Order) GetOrderID() string { func (m *Order) GetOrderID() int64 {
if m != nil { if m != nil {
return m.OrderID return m.OrderID
} }
return "" return 0
} }
func (m *Order) GetLimitOrder() *LimitOrder { func (m *Order) GetLimitOrder() *LimitOrder {
...@@ -554,56 +549,6 @@ func _Order_OneofSizer(msg proto.Message) (n int) { ...@@ -554,56 +549,6 @@ func _Order_OneofSizer(msg proto.Message) (n int) {
return n return n
} }
// 挂单价
type OrderPrice struct {
Price float64 `protobuf:"fixed64,1,opt,name=price" json:"price,omitempty"`
Index int64 `protobuf:"varint,2,opt,name=index" json:"index,omitempty"`
}
func (m *OrderPrice) Reset() { *m = OrderPrice{} }
func (m *OrderPrice) String() string { return proto.CompactTextString(m) }
func (*OrderPrice) ProtoMessage() {}
func (*OrderPrice) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *OrderPrice) GetPrice() float64 {
if m != nil {
return m.Price
}
return 0
}
func (m *OrderPrice) GetIndex() int64 {
if m != nil {
return m.Index
}
return 0
}
// 单号
type OrderID struct {
ID string `protobuf:"bytes,1,opt,name=ID" json:"ID,omitempty"`
Index int64 `protobuf:"varint,2,opt,name=index" json:"index,omitempty"`
}
func (m *OrderID) Reset() { *m = OrderID{} }
func (m *OrderID) String() string { return proto.CompactTextString(m) }
func (*OrderID) ProtoMessage() {}
func (*OrderID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
func (m *OrderID) GetID() string {
if m != nil {
return m.ID
}
return ""
}
func (m *OrderID) GetIndex() int64 {
if m != nil {
return m.Index
}
return 0
}
// 查询接口 // 查询接口
type QueryMarketDepth struct { type QueryMarketDepth struct {
// 资产1 // 资产1
...@@ -613,7 +558,7 @@ type QueryMarketDepth struct { ...@@ -613,7 +558,7 @@ type QueryMarketDepth struct {
// 操作, 1为买,2为卖 // 操作, 1为买,2为卖
Op int32 `protobuf:"varint,3,opt,name=op" json:"op,omitempty"` Op int32 `protobuf:"varint,3,opt,name=op" json:"op,omitempty"`
// 这里用价格作为索引值 // 这里用价格作为索引值
Price float64 `protobuf:"fixed64,4,opt,name=price" json:"price,omitempty"` PrimaryKey string `protobuf:"bytes,4,opt,name=primaryKey" json:"primaryKey,omitempty"`
// 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 // 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
Count int32 `protobuf:"varint,5,opt,name=count" json:"count,omitempty"` Count int32 `protobuf:"varint,5,opt,name=count" json:"count,omitempty"`
} }
...@@ -621,7 +566,7 @@ type QueryMarketDepth struct { ...@@ -621,7 +566,7 @@ type QueryMarketDepth struct {
func (m *QueryMarketDepth) Reset() { *m = QueryMarketDepth{} } func (m *QueryMarketDepth) Reset() { *m = QueryMarketDepth{} }
func (m *QueryMarketDepth) String() string { return proto.CompactTextString(m) } func (m *QueryMarketDepth) String() string { return proto.CompactTextString(m) }
func (*QueryMarketDepth) ProtoMessage() {} func (*QueryMarketDepth) ProtoMessage() {}
func (*QueryMarketDepth) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } func (*QueryMarketDepth) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *QueryMarketDepth) GetLeftAsset() *Asset { func (m *QueryMarketDepth) GetLeftAsset() *Asset {
if m != nil { if m != nil {
...@@ -644,11 +589,11 @@ func (m *QueryMarketDepth) GetOp() int32 { ...@@ -644,11 +589,11 @@ func (m *QueryMarketDepth) GetOp() int32 {
return 0 return 0
} }
func (m *QueryMarketDepth) GetPrice() float64 { func (m *QueryMarketDepth) GetPrimaryKey() string {
if m != nil { if m != nil {
return m.Price return m.PrimaryKey
} }
return 0 return ""
} }
func (m *QueryMarketDepth) GetCount() int32 { func (m *QueryMarketDepth) GetCount() int32 {
...@@ -675,7 +620,7 @@ type MarketDepth struct { ...@@ -675,7 +620,7 @@ type MarketDepth struct {
func (m *MarketDepth) Reset() { *m = MarketDepth{} } func (m *MarketDepth) Reset() { *m = MarketDepth{} }
func (m *MarketDepth) String() string { return proto.CompactTextString(m) } func (m *MarketDepth) String() string { return proto.CompactTextString(m) }
func (*MarketDepth) ProtoMessage() {} func (*MarketDepth) ProtoMessage() {}
func (*MarketDepth) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } func (*MarketDepth) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
func (m *MarketDepth) GetLeftAsset() *Asset { func (m *MarketDepth) GetLeftAsset() *Asset {
if m != nil { if m != nil {
...@@ -714,13 +659,14 @@ func (m *MarketDepth) GetOp() int32 { ...@@ -714,13 +659,14 @@ func (m *MarketDepth) GetOp() int32 {
// 查询接口返回的市场深度列表 // 查询接口返回的市场深度列表
type MarketDepthList struct { type MarketDepthList struct {
List []*MarketDepth `protobuf:"bytes,1,rep,name=list" json:"list,omitempty"` List []*MarketDepth `protobuf:"bytes,1,rep,name=list" json:"list,omitempty"`
PrimaryKey string `protobuf:"bytes,2,opt,name=primaryKey" json:"primaryKey,omitempty"`
} }
func (m *MarketDepthList) Reset() { *m = MarketDepthList{} } func (m *MarketDepthList) Reset() { *m = MarketDepthList{} }
func (m *MarketDepthList) String() string { return proto.CompactTextString(m) } func (m *MarketDepthList) String() string { return proto.CompactTextString(m) }
func (*MarketDepthList) ProtoMessage() {} func (*MarketDepthList) ProtoMessage() {}
func (*MarketDepthList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } func (*MarketDepthList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
func (m *MarketDepthList) GetList() []*MarketDepth { func (m *MarketDepthList) GetList() []*MarketDepth {
if m != nil { if m != nil {
...@@ -729,6 +675,13 @@ func (m *MarketDepthList) GetList() []*MarketDepth { ...@@ -729,6 +675,13 @@ func (m *MarketDepthList) GetList() []*MarketDepth {
return nil return nil
} }
func (m *MarketDepthList) GetPrimaryKey() string {
if m != nil {
return m.PrimaryKey
}
return ""
}
// 查询最新得成交信息,外部接口 // 查询最新得成交信息,外部接口
type QueryCompletedOrderList struct { type QueryCompletedOrderList struct {
// 资产1 // 资产1
...@@ -736,7 +689,7 @@ type QueryCompletedOrderList struct { ...@@ -736,7 +689,7 @@ type QueryCompletedOrderList struct {
// 资产2 // 资产2
RightAsset *Asset `protobuf:"bytes,2,opt,name=rightAsset" json:"rightAsset,omitempty"` RightAsset *Asset `protobuf:"bytes,2,opt,name=rightAsset" json:"rightAsset,omitempty"`
// 索引值 // 索引值
Index int64 `protobuf:"varint,3,opt,name=index" json:"index,omitempty"` PrimaryKey string `protobuf:"bytes,3,opt,name=primaryKey" json:"primaryKey,omitempty"`
// 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 // 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
Count int32 `protobuf:"varint,4,opt,name=count" json:"count,omitempty"` Count int32 `protobuf:"varint,4,opt,name=count" json:"count,omitempty"`
// 0降序,1升序,默认降序 // 0降序,1升序,默认降序
...@@ -746,7 +699,7 @@ type QueryCompletedOrderList struct { ...@@ -746,7 +699,7 @@ type QueryCompletedOrderList struct {
func (m *QueryCompletedOrderList) Reset() { *m = QueryCompletedOrderList{} } func (m *QueryCompletedOrderList) Reset() { *m = QueryCompletedOrderList{} }
func (m *QueryCompletedOrderList) String() string { return proto.CompactTextString(m) } func (m *QueryCompletedOrderList) String() string { return proto.CompactTextString(m) }
func (*QueryCompletedOrderList) ProtoMessage() {} func (*QueryCompletedOrderList) ProtoMessage() {}
func (*QueryCompletedOrderList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } func (*QueryCompletedOrderList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
func (m *QueryCompletedOrderList) GetLeftAsset() *Asset { func (m *QueryCompletedOrderList) GetLeftAsset() *Asset {
if m != nil { if m != nil {
...@@ -762,11 +715,11 @@ func (m *QueryCompletedOrderList) GetRightAsset() *Asset { ...@@ -762,11 +715,11 @@ func (m *QueryCompletedOrderList) GetRightAsset() *Asset {
return nil return nil
} }
func (m *QueryCompletedOrderList) GetIndex() int64 { func (m *QueryCompletedOrderList) GetPrimaryKey() string {
if m != nil { if m != nil {
return m.Index return m.PrimaryKey
} }
return 0 return ""
} }
func (m *QueryCompletedOrderList) GetCount() int32 { func (m *QueryCompletedOrderList) GetCount() int32 {
...@@ -785,19 +738,19 @@ func (m *QueryCompletedOrderList) GetDirection() int32 { ...@@ -785,19 +738,19 @@ func (m *QueryCompletedOrderList) GetDirection() int32 {
// 根据orderID去查询订单信息 // 根据orderID去查询订单信息
type QueryOrder struct { type QueryOrder struct {
OrderID string `protobuf:"bytes,1,opt,name=orderID" json:"orderID,omitempty"` OrderID int64 `protobuf:"varint,1,opt,name=orderID" json:"orderID,omitempty"`
} }
func (m *QueryOrder) Reset() { *m = QueryOrder{} } func (m *QueryOrder) Reset() { *m = QueryOrder{} }
func (m *QueryOrder) String() string { return proto.CompactTextString(m) } func (m *QueryOrder) String() string { return proto.CompactTextString(m) }
func (*QueryOrder) ProtoMessage() {} func (*QueryOrder) ProtoMessage() {}
func (*QueryOrder) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } func (*QueryOrder) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
func (m *QueryOrder) GetOrderID() string { func (m *QueryOrder) GetOrderID() int64 {
if m != nil { if m != nil {
return m.OrderID return m.OrderID
} }
return "" return 0
} }
// 根据地址,状态查询用户自己的挂单信息 // 根据地址,状态查询用户自己的挂单信息
...@@ -806,8 +759,8 @@ type QueryOrderList struct { ...@@ -806,8 +759,8 @@ type QueryOrderList struct {
Status int32 `protobuf:"varint,1,opt,name=status" json:"status,omitempty"` Status int32 `protobuf:"varint,1,opt,name=status" json:"status,omitempty"`
// 用户地址信息,必填 // 用户地址信息,必填
Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"`
// 索引值 // 主键索引
Index int64 `protobuf:"varint,3,opt,name=index" json:"index,omitempty"` PrimaryKey string `protobuf:"bytes,3,opt,name=primaryKey" json:"primaryKey,omitempty"`
// 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 // 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
Count int32 `protobuf:"varint,4,opt,name=count" json:"count,omitempty"` Count int32 `protobuf:"varint,4,opt,name=count" json:"count,omitempty"`
// 0降序,1升序,默认降序 // 0降序,1升序,默认降序
...@@ -817,7 +770,7 @@ type QueryOrderList struct { ...@@ -817,7 +770,7 @@ type QueryOrderList struct {
func (m *QueryOrderList) Reset() { *m = QueryOrderList{} } func (m *QueryOrderList) Reset() { *m = QueryOrderList{} }
func (m *QueryOrderList) String() string { return proto.CompactTextString(m) } func (m *QueryOrderList) String() string { return proto.CompactTextString(m) }
func (*QueryOrderList) ProtoMessage() {} func (*QueryOrderList) ProtoMessage() {}
func (*QueryOrderList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } func (*QueryOrderList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
func (m *QueryOrderList) GetStatus() int32 { func (m *QueryOrderList) GetStatus() int32 {
if m != nil { if m != nil {
...@@ -833,11 +786,11 @@ func (m *QueryOrderList) GetAddress() string { ...@@ -833,11 +786,11 @@ func (m *QueryOrderList) GetAddress() string {
return "" return ""
} }
func (m *QueryOrderList) GetIndex() int64 { func (m *QueryOrderList) GetPrimaryKey() string {
if m != nil { if m != nil {
return m.Index return m.PrimaryKey
} }
return 0 return ""
} }
func (m *QueryOrderList) GetCount() int32 { func (m *QueryOrderList) GetCount() int32 {
...@@ -856,13 +809,14 @@ func (m *QueryOrderList) GetDirection() int32 { ...@@ -856,13 +809,14 @@ func (m *QueryOrderList) GetDirection() int32 {
// 订单列表 // 订单列表
type OrderList struct { type OrderList struct {
List []*Order `protobuf:"bytes,1,rep,name=list" json:"list,omitempty"` List []*Order `protobuf:"bytes,1,rep,name=list" json:"list,omitempty"`
PrimaryKey string `protobuf:"bytes,2,opt,name=primaryKey" json:"primaryKey,omitempty"`
} }
func (m *OrderList) Reset() { *m = OrderList{} } func (m *OrderList) Reset() { *m = OrderList{} }
func (m *OrderList) String() string { return proto.CompactTextString(m) } func (m *OrderList) String() string { return proto.CompactTextString(m) }
func (*OrderList) ProtoMessage() {} func (*OrderList) ProtoMessage() {}
func (*OrderList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } func (*OrderList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
func (m *OrderList) GetList() []*Order { func (m *OrderList) GetList() []*Order {
if m != nil { if m != nil {
...@@ -871,6 +825,13 @@ func (m *OrderList) GetList() []*Order { ...@@ -871,6 +825,13 @@ func (m *OrderList) GetList() []*Order {
return nil return nil
} }
func (m *OrderList) GetPrimaryKey() string {
if m != nil {
return m.PrimaryKey
}
return ""
}
// exchange执行票据日志 // exchange执行票据日志
type ReceiptExchange struct { type ReceiptExchange struct {
Order *Order `protobuf:"bytes,1,opt,name=order" json:"order,omitempty"` Order *Order `protobuf:"bytes,1,opt,name=order" json:"order,omitempty"`
...@@ -881,7 +842,7 @@ type ReceiptExchange struct { ...@@ -881,7 +842,7 @@ type ReceiptExchange struct {
func (m *ReceiptExchange) Reset() { *m = ReceiptExchange{} } func (m *ReceiptExchange) Reset() { *m = ReceiptExchange{} }
func (m *ReceiptExchange) String() string { return proto.CompactTextString(m) } func (m *ReceiptExchange) String() string { return proto.CompactTextString(m) }
func (*ReceiptExchange) ProtoMessage() {} func (*ReceiptExchange) ProtoMessage() {}
func (*ReceiptExchange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } func (*ReceiptExchange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
func (m *ReceiptExchange) GetOrder() *Order { func (m *ReceiptExchange) GetOrder() *Order {
if m != nil { if m != nil {
...@@ -912,8 +873,6 @@ func init() { ...@@ -912,8 +873,6 @@ func init() {
proto.RegisterType((*RevokeOrder)(nil), "types.RevokeOrder") proto.RegisterType((*RevokeOrder)(nil), "types.RevokeOrder")
proto.RegisterType((*Asset)(nil), "types.asset") proto.RegisterType((*Asset)(nil), "types.asset")
proto.RegisterType((*Order)(nil), "types.Order") proto.RegisterType((*Order)(nil), "types.Order")
proto.RegisterType((*OrderPrice)(nil), "types.OrderPrice")
proto.RegisterType((*OrderID)(nil), "types.OrderID")
proto.RegisterType((*QueryMarketDepth)(nil), "types.QueryMarketDepth") proto.RegisterType((*QueryMarketDepth)(nil), "types.QueryMarketDepth")
proto.RegisterType((*MarketDepth)(nil), "types.MarketDepth") proto.RegisterType((*MarketDepth)(nil), "types.MarketDepth")
proto.RegisterType((*MarketDepthList)(nil), "types.MarketDepthList") proto.RegisterType((*MarketDepthList)(nil), "types.MarketDepthList")
...@@ -965,47 +924,46 @@ var _Exchange_serviceDesc = grpc.ServiceDesc{ ...@@ -965,47 +924,46 @@ var _Exchange_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("exchange.proto", fileDescriptor0) } func init() { proto.RegisterFile("exchange.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 659 bytes of a gzipped FileDescriptorProto // 647 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xed, 0x6a, 0xd4, 0x4c, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcf, 0x6e, 0xd3, 0x4e,
0x14, 0xee, 0xe4, 0xa3, 0xdb, 0x9c, 0x7d, 0xd9, 0xbe, 0x0e, 0xa2, 0x41, 0x44, 0x96, 0xfc, 0xa8, 0x10, 0xae, 0xed, 0xb8, 0xa9, 0x27, 0x3f, 0xa5, 0x3f, 0x56, 0x08, 0x2c, 0x84, 0x50, 0xe4, 0x43,
0x45, 0x74, 0x85, 0x16, 0xfc, 0xf8, 0x59, 0xad, 0xd0, 0x42, 0xa5, 0x3a, 0x78, 0x03, 0x69, 0x72, 0xa9, 0x10, 0xca, 0xa1, 0x95, 0xe0, 0x5c, 0x28, 0x52, 0x11, 0xad, 0x10, 0x2b, 0x2e, 0x1c, 0x5d,
0xec, 0x86, 0x66, 0x37, 0x21, 0x99, 0x2d, 0x5d, 0xbc, 0x05, 0xc1, 0x9b, 0x50, 0xf0, 0x26, 0xc4, 0x7b, 0x68, 0x56, 0xb5, 0x63, 0x6b, 0xbd, 0xa9, 0x1a, 0xf1, 0x10, 0xdc, 0x78, 0x02, 0x78, 0x01,
0x3b, 0xf0, 0x9a, 0x64, 0x4e, 0x26, 0x99, 0xd9, 0x76, 0xa5, 0xa2, 0xee, 0xbf, 0x3c, 0x73, 0x3e, 0x5e, 0x80, 0x23, 0x37, 0x9e, 0x09, 0xed, 0xec, 0x3a, 0xde, 0xa4, 0x45, 0xad, 0x40, 0xb9, 0xf9,
0xf2, 0x9c, 0x73, 0x9e, 0x33, 0x03, 0x03, 0xbc, 0x48, 0xc6, 0xf1, 0xf4, 0x14, 0x47, 0x65, 0x55, 0x9b, 0x7f, 0xfe, 0x66, 0xe6, 0xdb, 0x5d, 0x18, 0xe2, 0x65, 0x36, 0x49, 0xa7, 0x67, 0x38, 0xae,
0xc8, 0x82, 0xfb, 0x72, 0x5e, 0x62, 0x1d, 0x01, 0x6c, 0xbc, 0xd2, 0x86, 0xe8, 0x07, 0x83, 0x41, 0x65, 0xa5, 0x2a, 0x16, 0xaa, 0x79, 0x8d, 0x4d, 0x02, 0xb0, 0xf5, 0xca, 0x3a, 0x92, 0x5f, 0x1e,
0x0b, 0xf6, 0x12, 0x99, 0x15, 0x53, 0xbe, 0x0b, 0x90, 0x67, 0x93, 0x4c, 0x1e, 0x57, 0x29, 0x56, 0x0c, 0x5b, 0x70, 0x90, 0x29, 0x51, 0x4d, 0xd9, 0x3e, 0x40, 0x21, 0x4a, 0xa1, 0xde, 0xca, 0x1c,
0x21, 0x1b, 0xb2, 0xed, 0xfe, 0xce, 0x8d, 0x11, 0x85, 0x8e, 0x8e, 0x3a, 0xc3, 0xc1, 0x9a, 0xb0, 0x65, 0xec, 0x8d, 0xbc, 0xdd, 0xc1, 0xde, 0x9d, 0x31, 0xa5, 0x8e, 0x8f, 0x17, 0x8e, 0xa3, 0x0d,
0xdc, 0xf8, 0x13, 0xe8, 0x4f, 0xe2, 0xea, 0x0c, 0x75, 0x94, 0x43, 0x51, 0x5c, 0x47, 0xbd, 0x36, 0xee, 0x84, 0xb1, 0x67, 0x30, 0x28, 0x53, 0x79, 0x8e, 0x36, 0xcb, 0xa7, 0x2c, 0x66, 0xb3, 0x4e,
0x96, 0x83, 0x35, 0x61, 0x3b, 0xaa, 0xb8, 0x0a, 0xcf, 0x8b, 0x33, 0x6c, 0xe2, 0xdc, 0x85, 0x38, 0x3a, 0xcf, 0xd1, 0x06, 0x77, 0x03, 0x75, 0x9e, 0xc4, 0x8b, 0xea, 0x1c, 0x4d, 0x5e, 0xb0, 0x94,
0x61, 0x2c, 0x2a, 0xce, 0x72, 0xe4, 0x03, 0x70, 0xe4, 0x3c, 0x5c, 0x1f, 0xb2, 0x6d, 0x5f, 0x38, 0xc7, 0x3b, 0x8f, 0xce, 0x73, 0x02, 0xd9, 0x10, 0x7c, 0x35, 0x8f, 0x37, 0x47, 0xde, 0x6e, 0xc8,
0x72, 0xfe, 0xa2, 0x07, 0xfe, 0x79, 0x9c, 0xcf, 0x30, 0xfa, 0xcc, 0x00, 0x0c, 0x4b, 0xfe, 0x00, 0x7d, 0x35, 0x7f, 0xd1, 0x87, 0xf0, 0x22, 0x2d, 0x66, 0x98, 0x7c, 0xf5, 0x00, 0x3a, 0x96, 0xec,
0x82, 0x1c, 0xdf, 0xcb, 0xbd, 0xba, 0x46, 0xa9, 0x6b, 0xf9, 0x4f, 0x67, 0x8f, 0xd5, 0x99, 0x30, 0x09, 0x44, 0x05, 0x7e, 0x54, 0x07, 0x4d, 0x83, 0xca, 0xf6, 0xf2, 0x9f, 0xad, 0x9e, 0x6a, 0x1b,
0x66, 0xfe, 0x10, 0xa0, 0xca, 0x4e, 0xc7, 0xda, 0xd9, 0x59, 0xe2, 0x6c, 0xd9, 0xf9, 0x4d, 0xf0, 0xef, 0xdc, 0xec, 0x29, 0x80, 0x14, 0x67, 0x13, 0x1b, 0xec, 0x5f, 0x13, 0xec, 0xf8, 0xd9, 0x5d,
0xcb, 0x2a, 0x4b, 0x90, 0x38, 0x33, 0xd1, 0x00, 0x7e, 0x0b, 0xd6, 0xe3, 0x49, 0x31, 0x9b, 0xca, 0x08, 0x6b, 0x29, 0x32, 0x24, 0xce, 0x1e, 0x37, 0x80, 0xdd, 0x83, 0xcd, 0xb4, 0xac, 0x66, 0x53,
0xd0, 0x1b, 0xb2, 0x6d, 0x57, 0x68, 0xa4, 0xf8, 0x16, 0x65, 0xe8, 0x37, 0x7c, 0x8b, 0x32, 0xfa, 0x15, 0xf7, 0x46, 0xde, 0x6e, 0xc0, 0x2d, 0xd2, 0x7c, 0xab, 0x3a, 0x0e, 0x0d, 0xdf, 0xaa, 0x4e,
0xc4, 0xa0, 0x6f, 0xb5, 0x65, 0x85, 0x3c, 0x0d, 0x23, 0x77, 0x09, 0x23, 0xaf, 0x63, 0x74, 0x1f, 0x3e, 0x7b, 0x30, 0x70, 0xc6, 0xb2, 0x46, 0x9e, 0x1d, 0xa3, 0xe0, 0x1a, 0x46, 0xbd, 0x05, 0xa3,
0xfa, 0x56, 0xbf, 0x79, 0x08, 0xbd, 0x42, 0x7d, 0x1c, 0xee, 0x13, 0x9d, 0x40, 0xb4, 0x30, 0x7a, 0xc7, 0x30, 0x70, 0xe6, 0xcd, 0x62, 0xe8, 0x57, 0xfa, 0xe3, 0xf5, 0x21, 0xd1, 0x09, 0x78, 0x0b,
0x0a, 0x7e, 0xdc, 0x66, 0xc6, 0x0b, 0x4c, 0xb4, 0x48, 0x02, 0xa1, 0x91, 0x3a, 0xaf, 0xe7, 0x93, 0x93, 0xe7, 0x10, 0xa6, 0x6d, 0x65, 0xbc, 0xc4, 0xcc, 0x8a, 0x24, 0xe2, 0x16, 0x69, 0x7b, 0x33,
0x93, 0x22, 0x27, 0x6e, 0x81, 0xd0, 0x28, 0xfa, 0xee, 0x80, 0x7f, 0x4d, 0xf2, 0x4b, 0xe2, 0x73, 0x2f, 0x4f, 0xab, 0x82, 0xb8, 0x45, 0xdc, 0xa2, 0xe4, 0x87, 0x0f, 0xe1, 0x0d, 0xc5, 0x57, 0xc4,
0xfe, 0x48, 0x7c, 0xee, 0xef, 0x8a, 0xaf, 0x11, 0x91, 0xd7, 0x8a, 0x88, 0xdf, 0x81, 0x0d, 0x55, 0xe7, 0xff, 0x95, 0xf8, 0x82, 0xdb, 0x8a, 0xcf, 0x88, 0xa8, 0xd7, 0x8a, 0x88, 0x3d, 0x80, 0x2d,
0xc2, 0x4c, 0x62, 0x4a, 0xa3, 0x72, 0x45, 0x87, 0x15, 0xe5, 0x93, 0x38, 0x8f, 0xa7, 0x09, 0x92, 0xdd, 0xc2, 0x4c, 0x61, 0x4e, 0xab, 0x0a, 0xf8, 0x02, 0x6b, 0xca, 0xa7, 0x69, 0x91, 0x4e, 0x33,
0xea, 0x5c, 0xd1, 0x42, 0x2a, 0x57, 0xc6, 0x72, 0x56, 0x87, 0x3d, 0xca, 0xa4, 0x11, 0xe7, 0xe0, 0x24, 0xd5, 0x05, 0xbc, 0x85, 0xd4, 0xae, 0x4a, 0xd5, 0xac, 0x89, 0xfb, 0x54, 0xc9, 0x22, 0xc6,
0xc5, 0x69, 0x5a, 0x85, 0x1b, 0x54, 0x21, 0x7d, 0xf3, 0x7b, 0x00, 0xb3, 0x32, 0x8d, 0x25, 0xbe, 0xa0, 0x97, 0xe6, 0xb9, 0x8c, 0xb7, 0x68, 0x08, 0xf4, 0xcd, 0x1e, 0x01, 0xcc, 0xea, 0x3c, 0x55,
0xcb, 0x26, 0x18, 0x06, 0x94, 0xc8, 0x3a, 0x51, 0xa2, 0xca, 0xa6, 0x29, 0x5e, 0x84, 0x40, 0xa6, 0xf8, 0x5e, 0x94, 0x18, 0x47, 0x54, 0xc8, 0xb1, 0x68, 0x51, 0x89, 0x69, 0x8e, 0x97, 0x31, 0x90,
0x06, 0x18, 0x71, 0x3f, 0x03, 0x20, 0xe6, 0x6f, 0x48, 0x6b, 0x9d, 0x02, 0x99, 0xad, 0xc0, 0x2e, 0xcb, 0x80, 0x4e, 0xdc, 0xdf, 0x3d, 0xf8, 0xff, 0xdd, 0x0c, 0xe5, 0xdc, 0x34, 0x75, 0x88, 0xb5,
0x85, 0x63, 0xa5, 0x88, 0x1e, 0x43, 0xef, 0x58, 0xb7, 0x78, 0x00, 0x4e, 0xd7, 0x77, 0xe7, 0x70, 0x9a, 0xac, 0x51, 0x3a, 0x46, 0x22, 0x41, 0x2b, 0x11, 0xcd, 0xbe, 0x96, 0xa2, 0x4c, 0xe5, 0xfc,
0xff, 0x17, 0x01, 0x5f, 0x19, 0xfc, 0xff, 0x76, 0x86, 0xd5, 0xbc, 0xe9, 0xdf, 0x3e, 0x96, 0x72, 0x0d, 0x9a, 0xb9, 0x45, 0xdc, 0xb1, 0x68, 0xf6, 0x19, 0x29, 0xcd, 0xe8, 0xdc, 0x80, 0xe4, 0xdb,
0xbc, 0x42, 0x95, 0x36, 0x6a, 0x74, 0x5b, 0x35, 0x9a, 0xda, 0xbc, 0x4b, 0xb5, 0x25, 0x24, 0xe5, 0x42, 0xea, 0xeb, 0xe6, 0xfb, 0x6f, 0x47, 0xf2, 0x03, 0x6c, 0x3b, 0x34, 0x8f, 0x45, 0xa3, 0xd8,
0x66, 0x91, 0x1a, 0x10, 0x7d, 0xe9, 0x76, 0x69, 0xd5, 0x2c, 0xff, 0x6e, 0xe7, 0x9f, 0xc3, 0xa6, 0x0e, 0xf4, 0x0a, 0xd1, 0x68, 0x96, 0xc1, 0x15, 0x45, 0x51, 0x14, 0x27, 0xff, 0xca, 0x60, 0xfc,
0x45, 0xf3, 0x28, 0xab, 0x25, 0xdf, 0x02, 0x2f, 0xcf, 0x6a, 0xc5, 0xd2, 0xbd, 0x22, 0x59, 0xf2, 0xd5, 0xc1, 0x24, 0x3f, 0x3d, 0xb8, 0x4f, 0x7b, 0x7b, 0x59, 0x95, 0x75, 0x81, 0x0a, 0x73, 0x12,
0x12, 0x64, 0x8f, 0xbe, 0x31, 0xb8, 0x4d, 0xd3, 0x78, 0x59, 0x4c, 0xca, 0x1c, 0x25, 0xa6, 0x34, 0x20, 0xfd, 0x63, 0x7d, 0xe3, 0x58, 0x66, 0x15, 0xfc, 0x79, 0x5d, 0x3d, 0x67, 0x5d, 0xec, 0x21,
0x4d, 0xca, 0xb1, 0xd2, 0x72, 0x1b, 0x65, 0xb8, 0x96, 0x32, 0xcc, 0x10, 0x3c, 0x6b, 0x08, 0xfc, 0x44, 0xb9, 0x90, 0x48, 0x6f, 0x81, 0x9d, 0x4e, 0x67, 0x48, 0x76, 0x00, 0xa8, 0x91, 0x9b, 0x2e,
0x2e, 0x04, 0x69, 0x56, 0x21, 0x3d, 0x21, 0xba, 0x66, 0x73, 0x10, 0x6d, 0x01, 0x10, 0xfd, 0xeb, 0x89, 0x2f, 0x1e, 0x0c, 0xbb, 0x40, 0x6a, 0xb4, 0x3b, 0x27, 0xde, 0xd2, 0x39, 0x89, 0xa1, 0xaf,
0xee, 0x96, 0x8f, 0x0c, 0x06, 0xc6, 0x91, 0xca, 0x33, 0xeb, 0xc5, 0x16, 0xd6, 0x2b, 0x84, 0x9e, 0xcf, 0x06, 0x36, 0x8d, 0x9d, 0x5c, 0x0b, 0xd7, 0xd2, 0xc0, 0x09, 0x44, 0x1d, 0xa5, 0xd1, 0xd2,
0x5a, 0x29, 0xac, 0x6b, 0x7d, 0xcd, 0xb4, 0xf0, 0x1f, 0xd2, 0x7e, 0x04, 0x81, 0x21, 0x32, 0x5c, 0x7e, 0xdb, 0x49, 0x92, 0xff, 0x96, 0x9b, 0xfd, 0x04, 0xdb, 0x1c, 0x33, 0x14, 0xb5, 0x6a, 0x5f,
0x98, 0x55, 0xdb, 0x35, 0xb2, 0xeb, 0x29, 0x7d, 0x80, 0x4d, 0x81, 0x09, 0x66, 0xa5, 0x6c, 0x9f, 0x51, 0x96, 0x40, 0x58, 0x39, 0x4f, 0xe7, 0x72, 0x55, 0xe3, 0x62, 0x63, 0x7d, 0x63, 0xa9, 0x6c,
0x54, 0x1e, 0x81, 0x5f, 0x58, 0xef, 0xe8, 0x62, 0x54, 0x63, 0xe2, 0x23, 0x75, 0x7d, 0xc9, 0x64, 0x42, 0x46, 0xdd, 0xf7, 0xd5, 0xff, 0xbb, 0x01, 0xdd, 0xbd, 0x10, 0x38, 0xf7, 0xc2, 0x1e, 0xe8,
0x4c, 0x87, 0xaa, 0x9a, 0xab, 0xf9, 0x6d, 0x87, 0xe5, 0xf5, 0xed, 0x80, 0xba, 0xbc, 0x9a, 0xbf, 0xfb, 0xca, 0xfc, 0xf5, 0x74, 0x93, 0x9e, 0xf8, 0xfd, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf3,
0x9e, 0xac, 0xd3, 0x7b, 0xbf, 0xfb, 0x33, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xc6, 0x87, 0x60, 0x01, 0x6d, 0x05, 0xfd, 0xf4, 0x07, 0x00, 0x00,
0x08, 0x00, 0x00,
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment