Commit 5d8922a2 authored by harrylee's avatar harrylee Committed by vipwzw

add exchange_test.go

parent ef710316
This diff is collapsed.
package executor package executor
import ( import (
"fmt"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
exchangetypes "github.com/33cn/plugin/plugin/dapp/exchange/types" exchangetypes "github.com/33cn/plugin/plugin/dapp/exchange/types"
) )
...@@ -11,19 +12,16 @@ import ( ...@@ -11,19 +12,16 @@ import (
*/ */
func (e *exchange) Exec_LimitOrder(payload *exchangetypes.LimitOrder, tx *types.Transaction, index int) (*types.Receipt, error) { func (e *exchange) Exec_LimitOrder(payload *exchangetypes.LimitOrder, tx *types.Transaction, index int) (*types.Receipt, error) {
var receipt *types.Receipt action := NewAction(e, tx, index)
//implement code return action.LimitOrder(payload)
return receipt, nil
} }
func (e *exchange) Exec_MarketOrder(payload *exchangetypes.MarketOrder, tx *types.Transaction, index int) (*types.Receipt, error) { func (e *exchange) Exec_MarketOrder(payload *exchangetypes.MarketOrder, tx *types.Transaction, index int) (*types.Receipt, error) {
var receipt *types.Receipt //TODO marketOrder
//implement code return nil, fmt.Errorf("%s", "not support MarketOrder..")
return receipt, nil
} }
func (e *exchange) Exec_RevokeOrder(payload *exchangetypes.RevokeOrder, tx *types.Transaction, index int) (*types.Receipt, error) { func (e *exchange) Exec_RevokeOrder(payload *exchangetypes.RevokeOrder, tx *types.Transaction, index int) (*types.Receipt, error) {
var receipt *types.Receipt action := NewAction(e, tx, index)
//implement code return action.RevokeOrder(payload)
return receipt, nil
} }
...@@ -30,13 +30,37 @@ func (e *exchange) ExecLocal_LimitOrder(payload *exchangetypes.LimitOrder, tx *t ...@@ -30,13 +30,37 @@ func (e *exchange) ExecLocal_LimitOrder(payload *exchangetypes.LimitOrder, tx *t
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 *exchangetypes.MarketOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{} dbSet := &types.LocalDBSet{}
//implement code if receiptData.Ty == types.ExecOk {
for _, log := range receiptData.Logs {
switch log.Ty {
case exchangetypes.TyMarketOrderLog:
receipt := &exchangetypes.ReceiptExchange{}
if err := types.Decode(log.Log, receipt); err != nil {
return nil, err
}
kv := e.updateIndex(receipt)
dbSet.KV = append(dbSet.KV, kv...)
}
}
}
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 *exchangetypes.RevokeOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{} dbSet := &types.LocalDBSet{}
//implement code if receiptData.Ty == types.ExecOk {
for _, log := range receiptData.Logs {
switch log.Ty {
case exchangetypes.TyRevokeOrderLog:
receipt := &exchangetypes.ReceiptExchange{}
if err := types.Decode(log.Log, receipt); err != nil {
return nil, err
}
kv := e.updateIndex(receipt)
dbSet.KV = append(dbSet.KV, kv...)
}
}
}
return e.addAutoRollBack(tx, dbSet.KV), nil return e.addAutoRollBack(tx, dbSet.KV), nil
} }
...@@ -66,8 +90,10 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -66,8 +90,10 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
markDepth.RightAsset = right markDepth.RightAsset = right
markDepth.Op = op markDepth.Op = op
markDepth.Amount = receipt.Order.Balance markDepth.Amount = receipt.Order.Balance
} else {
markDepth.Amount = markDepth.Amount + receipt.Order.Balance
} }
markDepth.Amount = markDepth.Amount + receipt.Order.Balance
//marketDepth //marketDepth
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, op, price), Value: types.Encode(&markDepth)}) kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, op, price), Value: types.Encode(&markDepth)})
//orderID //orderID
...@@ -78,23 +104,23 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -78,23 +104,23 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
if len(receipt.MatchOrders) > 0 { if len(receipt.MatchOrders) > 0 {
//撮合交易更新 //撮合交易更新
var balance int64 var balance int64
for _, matchOrder := range receipt.MatchOrders { for i, matchOrder := range receipt.MatchOrders {
if matchOrder.Status == exchangetypes.Completed { if matchOrder.Status == exchangetypes.Completed {
// 删除原有状态orderID // 删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, matchOrder.GetLimitOrder().Op, price, matchOrder.Index), Value: nil}) kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, matchOrder.GetLimitOrder().Op, price, matchOrder.Index), Value: nil})
//删除原有状态orderID //删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, matchOrder.Addr, matchOrder.Index), Value: nil}) kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, matchOrder.Addr, matchOrder.Index), Value: nil})
//更新状态为已完成,索引index,改为当前的index //更新状态为已完成,索引index,改为当前的index
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Completed, matchOrder.Addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, 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)})})
//calcCompletedOrderKey //calcCompletedOrderKey
kvs = append(kvs, &types.KeyValue{Key: calcCompletedOrderKey(left, right, index), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, Index: index})}) 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)})})
} }
if matchOrder.Status == exchangetypes.Ordered { if matchOrder.Status == exchangetypes.Ordered {
//只需统一更改市场深度状态,其他不需要处理 //只需统一更改市场深度状态,其他不需要处理
balance = balance + matchOrder.Balance balance = balance + matchOrder.Balance
} }
} }
//更改市场深度 //更改匹配市场深度
var matchDepth exchangetypes.MarketDepth var matchDepth exchangetypes.MarketDepth
err = findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), price), &matchDepth) err = findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), price), &matchDepth)
if err == types.ErrNotFound { if err == types.ErrNotFound {
...@@ -103,10 +129,15 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -103,10 +129,15 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
matchDepth.RightAsset = right matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op) matchDepth.Op = OpSwap(op)
matchDepth.Amount = balance matchDepth.Amount = balance
} else {
matchDepth.Amount = matchDepth.Amount - receipt.Order.Executed
} }
matchDepth.Amount = matchDepth.Amount - receipt.Order.Executed
//marketDepth //marketDepth
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: types.Encode(&matchDepth)}) kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: types.Encode(&matchDepth)})
if matchDepth.Amount == 0 {
//删除
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: nil})
}
} }
return return
case exchangetypes.Completed: case exchangetypes.Completed:
...@@ -121,19 +152,22 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -121,19 +152,22 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
//user orderID //user orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Completed, addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})}) kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Completed, addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})})
//calcCompletedOrderKey
kvs = append(kvs, &types.KeyValue{Key: calcCompletedOrderKey(left, right, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})})
if len(receipt.MatchOrders) > 0 { if len(receipt.MatchOrders) > 0 {
//撮合交易更新 //撮合交易更新
var balance int64 var balance int64
for _, matchOrder := range receipt.MatchOrders { for i, matchOrder := range receipt.MatchOrders {
if matchOrder.Status == exchangetypes.Completed { if matchOrder.Status == exchangetypes.Completed {
// 删除原有状态orderID // 删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, matchOrder.GetLimitOrder().Op, price, matchOrder.Index), Value: nil}) kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, matchOrder.GetLimitOrder().Op, price, matchOrder.Index), Value: nil})
//删除原有状态orderID //删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, matchOrder.Addr, matchOrder.Index), Value: nil}) kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, matchOrder.Addr, matchOrder.Index), Value: nil})
//更新状态为已完成,更新索引 //更新状态为已完成,更新索引
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Completed, matchOrder.Addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, 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)})})
//calcCompletedOrderKey //calcCompletedOrderKey
kvs = append(kvs, &types.KeyValue{Key: calcCompletedOrderKey(left, right, index), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, Index: index})}) 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)})})
} }
if matchOrder.Status == exchangetypes.Ordered { if matchOrder.Status == exchangetypes.Ordered {
...@@ -150,10 +184,15 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -150,10 +184,15 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
matchDepth.RightAsset = right matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op) matchDepth.Op = OpSwap(op)
matchDepth.Amount = balance matchDepth.Amount = balance
} else {
matchDepth.Amount = matchDepth.Amount - receipt.Order.Executed
} }
matchDepth.Amount = matchDepth.Amount - receipt.Order.Executed
//marketDepth //marketDepth
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: types.Encode(&matchDepth)}) kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: types.Encode(&matchDepth)})
if matchDepth.Amount == 0 {
//删除
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: nil})
}
} }
return return
case exchangetypes.Revoked: case exchangetypes.Revoked:
...@@ -170,8 +209,14 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -170,8 +209,14 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
if err == nil { if err == nil {
//marketDepth //marketDepth
marketDepth.Amount = marketDepth.Amount - receipt.GetOrder().Balance marketDepth.Amount = marketDepth.Amount - receipt.GetOrder().Balance
elog.Error("revoked", "recept.order.balance", receipt.GetOrder().Balance)
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, op, price), Value: types.Encode(&marketDepth)}) kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, op, price), Value: types.Encode(&marketDepth)})
} }
elog.Error("revoked", "marketDepth.Amount", marketDepth.Amount)
if marketDepth.Amount == 0 {
//删除
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, op, price), Value: nil})
}
// 删除原有状态orderID // 删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, op, price, receipt.GetOrder().Index), Value: nil}) kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, op, price, receipt.GetOrder().Index), Value: nil})
//删除原有状态orderID //删除原有状态orderID
......
...@@ -45,14 +45,15 @@ func calcMarketDepthOrderPrefix(left, right *types.Asset, op int32, price float3 ...@@ -45,14 +45,15 @@ func calcMarketDepthOrderPrefix(left, right *types.Asset, op int32, price float3
// localdb中存储市场挂单ID // localdb中存储市场挂单ID
func calcMarketDepthOrderKey(left, right *types.Asset, op int32, price float32, index int64) []byte { func calcMarketDepthOrderKey(left, right *types.Asset, op int32, price float32, index int64) []byte {
// 设置精度为1e8 // 设置精度为1e8
key := fmt.Sprintf("%s"+"order-%s-%s-%d:%016d:%018d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float32(1e8)), index) key := fmt.Sprintf("%s"+"order-%s-%s-%d:%016d:%022d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float32(1e8)), index)
return []byte(key) return []byte(key)
} }
//最新已经成交的订单,这里状态固定都是完成状态,这个主要给外部使用,可以查询最新得成交信息 //最新已经成交的订单,这里状态固定都是完成状态,这个主要给外部使用,可以查询最新得成交信息,存在多个情况
//matchOrderIndex,是匹配order在数组中的index,这里预留4个0000,用来解决同一笔交易中存在key重复得情况,这样设计保证了key得唯一性
func calcCompletedOrderKey(left, right *types.Asset, index int64) []byte { func calcCompletedOrderKey(left, right *types.Asset, index int64) []byte {
// 设置精度为1e8 // 设置精度为1e8
key := fmt.Sprintf("%s"+"completed-%s-%s-%d:%018d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), types.Completed, index) key := fmt.Sprintf("%s"+"completed-%s-%s-%d:%022d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), types.Completed, index)
return []byte(key) return []byte(key)
} }
func calcCompletedOrderPrefix(left, right *types.Asset) []byte { func calcCompletedOrderPrefix(left, right *types.Asset) []byte {
...@@ -66,7 +67,8 @@ func calcUserOrderIDPrefix(status int32, addr string) []byte { ...@@ -66,7 +67,8 @@ func calcUserOrderIDPrefix(status int32, addr string) []byte {
key := fmt.Sprintf("%s"+"addr:%s:%d:", KeyPrefixLocalDB, addr, status) key := fmt.Sprintf("%s"+"addr:%s:%d:", KeyPrefixLocalDB, addr, status)
return []byte(key) return []byte(key)
} }
//matchOrderIndex,用来解决同一笔交易中存在key重复得情况,这样设计保证了key得唯一性
func calcUserOrderIDKey(status int32, addr string, index int64) []byte { func calcUserOrderIDKey(status int32, addr string, index int64) []byte {
key := fmt.Sprintf("%s"+"addr:%s:%d:%018d", KeyPrefixLocalDB, addr, status, index) key := fmt.Sprintf("%s"+"addr:%s:%d:%022d", KeyPrefixLocalDB, addr, status, index)
return []byte(key) return []byte(key)
} }
...@@ -16,9 +16,6 @@ func (s *exchange) Query_QueryMarketDepth(in *et.QueryMarketDepth) (types.Messag ...@@ -16,9 +16,6 @@ func (s *exchange) Query_QueryMarketDepth(in *et.QueryMarketDepth) (types.Messag
if !CheckExchangeAsset(in.LeftAsset, in.RightAsset) { if !CheckExchangeAsset(in.LeftAsset, in.RightAsset) {
return nil, et.ErrAsset return nil, et.ErrAsset
} }
if !CheckPrice(in.Price) {
return nil, et.ErrAssetPrice
}
if !CheckOp(in.Op) { if !CheckOp(in.Op) {
return nil, et.ErrAssetOp return nil, et.ErrAssetOp
......
...@@ -7,7 +7,7 @@ message Exchange { ...@@ -7,7 +7,7 @@ message Exchange {
message ExchangeAction { message ExchangeAction {
oneof value { oneof value {
LimitOrder limitOrder = 1; LimitOrder limitOrder = 1;
// MarketOrder marketOrder = 2; MarketOrder marketOrder = 2;
RevokeOrder revokeOrder = 3; RevokeOrder revokeOrder = 3;
} }
int32 ty = 6; int32 ty = 6;
......
This diff is collapsed.
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