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

add exchange_test.go

parent ef710316
...@@ -35,7 +35,8 @@ func NewAction(e *exchange, tx *types.Transaction, index int) *Action { ...@@ -35,7 +35,8 @@ func NewAction(e *exchange, tx *types.Transaction, index int) *Action {
//GetIndex get index //GetIndex get index
func (a *Action) GetIndex() int64 { func (a *Action) GetIndex() int64 {
return a.height*types.MaxTxsPerBlock + int64(a.index) //扩容4个0,用于匹配多个matchorder索引时使用
return (a.height*types.MaxTxsPerBlock + int64(a.index)) * 1e4
} }
//GetKVSet get kv set //GetKVSet get kv set
...@@ -66,9 +67,9 @@ func (a *Action) calcActualCost(op int32, amount int64, price float32) int64 { ...@@ -66,9 +67,9 @@ func (a *Action) calcActualCost(op int32, amount int64, price float32) int64 {
return amount return amount
} }
//price 精度允许范围小数点后面7位数,整数是1e8 //price 精度允许范围小数点后面7位数,0<price<1e8
func CheckPrice(price float32) bool { func CheckPrice(price float32) bool {
if (Truncate(price) > 1e8) || (Truncate(price)*float32(1e8) <= 0) { if (Truncate(price) >= 1e8) || (Truncate(price)*float32(1e8) <= 0) {
return false return false
} }
return true return true
...@@ -122,7 +123,7 @@ func (a *Action) LimitOrder(payload *et.LimitOrder) (*types.Receipt, error) { ...@@ -122,7 +123,7 @@ func (a *Action) LimitOrder(payload *et.LimitOrder) (*types.Receipt, error) {
if !types.CheckAmount(payload.GetAmount()) { if !types.CheckAmount(payload.GetAmount()) {
return nil, et.ErrAssetAmount return nil, et.ErrAssetAmount
} }
if CheckPrice(payload.GetPrice()) { if !CheckPrice(payload.GetPrice()) {
return nil, et.ErrAssetPrice return nil, et.ErrAssetPrice
} }
if !CheckOp(payload.GetOp()) { if !CheckOp(payload.GetOp()) {
...@@ -188,7 +189,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) { ...@@ -188,7 +189,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
amount := int64(float32(balance) * price) amount := a.calcActualCost(et.OpBuy, balance, price)
rightAccount := rightAssetDB.LoadExecAccount(a.fromaddr, a.execaddr) rightAccount := rightAssetDB.LoadExecAccount(a.fromaddr, a.execaddr)
if rightAccount.Frozen < amount { if rightAccount.Frozen < amount {
elog.Error("RevokeOrder.BalanceCheck", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", amount, "err", et.ErrAssetBalance.Error()) elog.Error("RevokeOrder.BalanceCheck", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", amount, "err", et.ErrAssetBalance.Error())
...@@ -207,7 +208,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) { ...@@ -207,7 +208,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
amount := balance amount := a.calcActualCost(et.OpBuy, balance, price)
leftAccount := leftAssetDB.LoadExecAccount(a.fromaddr, a.execaddr) leftAccount := leftAssetDB.LoadExecAccount(a.fromaddr, a.execaddr)
if leftAccount.Frozen < amount { if leftAccount.Frozen < amount {
elog.Error("RevokeOrder.BalanceCheck", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", amount, "err", et.ErrAssetBalance.Error()) elog.Error("RevokeOrder.BalanceCheck", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", amount, "err", et.ErrAssetBalance.Error())
...@@ -281,10 +282,29 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -281,10 +282,29 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
} }
//TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生 //TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生
if matchorder.GetBalance() >= or.GetBalance() { if matchorder.GetBalance() >= or.GetBalance() {
if payload.Op == et.OpSell {
//转移冻结资产
receipt, err := rightAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), payload.GetPrice()))
if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), payload.GetPrice()), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
//将达成交易的相应资产结算
receipt, err = leftAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, a.calcActualCost(payload.Op, or.GetBalance(), payload.GetPrice()))
if err != nil {
elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(payload.Op, or.GetBalance(), payload.GetPrice()), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
}
if payload.Op == et.OpBuy {
//转移冻结资产 //转移冻结资产
receipt, err := leftAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), payload.GetPrice())) receipt, err := leftAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), payload.GetPrice()))
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), payload.GetPrice()), "err", err.Error()) elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), payload.GetPrice()), "err", err.Error())
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
...@@ -297,9 +317,9 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -297,9 +317,9 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
// match receiptorder }
matchorder.Balance = matchorder.GetBalance() - or.GetBalance()
matchorder.Executed = matchorder.Executed + or.GetBalance() // match receiptorder,涉及赋值先手顺序,代码顺序不可变
matchorder.Status = func(a, b int64) int32 { matchorder.Status = func(a, b int64) int32 {
if a > b { if a > b {
return et.Ordered return et.Ordered
...@@ -307,12 +327,15 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -307,12 +327,15 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
return et.Completed return et.Completed
} }
}(matchorder.GetBalance(), or.GetBalance()) }(matchorder.GetBalance(), or.GetBalance())
matchorder.Balance = matchorder.GetBalance() - or.GetBalance()
matchorder.Executed = matchorder.Executed + or.GetBalance()
a.updateStateDBCache(matchorder) a.updateStateDBCache(matchorder)
kvs = append(kvs, a.GetKVSet(matchorder)...) kvs = append(kvs, a.GetKVSet(matchorder)...)
or.Balance = 0
or.Executed = or.Executed + or.GetBalance() or.Executed = or.Executed + or.GetBalance()
or.Status = et.Completed or.Status = et.Completed
or.Balance = 0
//update receipt order //update receipt order
re.Order = or re.Order = or
re.MatchOrders = append(re.MatchOrders, matchorder) re.MatchOrders = append(re.MatchOrders, matchorder)
...@@ -325,10 +348,29 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -325,10 +348,29 @@ 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
} else { } else {
if payload.Op == et.OpSell {
//转移冻结资产
receipt, err := rightAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.GetPrice()))
if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.GetPrice()), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
//将达成交易的相应资产结算
receipt, err = leftAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, a.calcActualCost(payload.Op, matchorder.GetBalance(), payload.GetPrice()))
if err != nil {
elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(payload.Op, matchorder.GetBalance(), payload.GetPrice()), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
}
if payload.Op == et.OpBuy {
//转移冻结资产 //转移冻结资产
receipt, err := leftAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.GetPrice())) receipt, err := leftAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.GetPrice()))
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.GetPrice()), "err", err.Error()) elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.GetPrice()), "err", err.Error())
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
...@@ -341,23 +383,23 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -341,23 +383,23 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
}
//涉及赋值先后顺序,不可颠倒
or.Balance = or.Balance - matchorder.Balance
or.Executed = or.Executed + matchorder.Balance
or.Status = et.Ordered
a.updateStateDBCache(or)
// match receiptorder // match receiptorder
matchorder.Balance = 0
matchorder.Executed = matchorder.Executed + matchorder.GetBalance() matchorder.Executed = matchorder.Executed + matchorder.GetBalance()
matchorder.Status = et.Completed matchorder.Status = et.Completed
matchorder.Balance = 0
a.updateStateDBCache(matchorder) a.updateStateDBCache(matchorder)
kvs = append(kvs, a.GetKVSet(matchorder)...) kvs = append(kvs, a.GetKVSet(matchorder)...)
or.Balance = or.Balance - matchorder.Balance
or.Executed = or.Executed + matchorder.Balance
or.Status = et.Ordered
re.Order = or re.Order = or
re.MatchOrders = append(re.MatchOrders, matchorder) re.MatchOrders = append(re.MatchOrders, matchorder)
a.updateStateDBCache(or)
} }
} }
//查询数据不满足5条说明没有了,跳出循环 //查询数据不满足5条说明没有了,跳出循环
......
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