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

add some test

parent a3f2a08e
......@@ -63,7 +63,7 @@ func TestExchange(t *testing.T) {
Addr: string(Nodes[3]),
}
execAddr := address.ExecAddress(et.ExchangeX)
stateDB, _ := dbm.NewGoMemDB("1", "2", 1000)
stateDB, _ := dbm.NewGoMemDB("1", "2", 5000)
_, _, kvdb := util.CreateTestDB()
accA, _ := account.NewAccountDB(cfg, "coins", "bty", stateDB)
......@@ -440,10 +440,14 @@ func TestExchange(t *testing.T) {
t.Log(reply2)
assert.Equal(t, 2, len(reply2.List))
//低于市场价得卖单测试
acc = accD1.LoadExecAccount(string(Nodes[3]), execAddr)
t.Log(acc)
acc = accC.LoadExecAccount(string(Nodes[2]), execAddr)
t.Log(acc)
//低于市场价得卖单测试
// orderlimit bty:CCNY
// orderlimit bty:CCNY ,先挂买单,然后低于市场价格卖出
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.OpBuy})
assert.Nil(t, err)
......@@ -501,6 +505,7 @@ func TestExchange(t *testing.T) {
stateDB.Set(kv.Key, kv.Value)
}
receiptData = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
t.Log(receiptData.Ty)
set, err = exec.ExecLocal(tx, receiptData, int(1))
if err != nil {
t.Error(err)
......@@ -517,16 +522,147 @@ func TestExchange(t *testing.T) {
}
t.Log(msg)
reply = msg.(*et.Order)
acc = accD1.LoadExecAccount(string(Nodes[2]), execAddr)
assert.Equal(t, int32(et.Completed), reply.Status)
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID7}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply = msg.(*et.Order)
assert.Equal(t, int32(et.Ordered), reply.Status)
acc = accD1.LoadExecAccount(string(Nodes[3]), execAddr)
t.Log(acc)
assert.Equal(t, 85*types.Coin, acc.Balance)
acc = accC.LoadExecAccount(string(Nodes[2]), execAddr)
t.Log(acc)
//assert.Equal(t, int32(et.Completed), reply.Status)
// orderlimit bty:CCNY ,先挂卖单,然后高于市场价格买入, 买家获利原则
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})
assert.Nil(t, err)
tx, err = types.FormatTx(cfg, et.ExchangeX, tx)
assert.Nil(t, err)
tx, err = signTx(tx, PrivKeyC)
assert.Nil(t, err)
err = e.CheckTx(tx, 1)
assert.Nil(t, err)
env.blockHeight = env.blockHeight + 1
env.blockTime = env.blockTime + 20
env.difficulty = env.difficulty + 1
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
receipt, err = exec.Exec(tx, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
receiptData = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
t.Log(receiptData.Ty)
set, err = exec.ExecLocal(tx, receiptData, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
orderID8 := common.ToHex(tx.Hash())
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})
assert.Nil(t, err)
tx, err = types.FormatTx(cfg, et.ExchangeX, tx)
assert.Nil(t, err)
tx, err = signTx(tx, PrivKeyC)
assert.Nil(t, err)
err = e.CheckTx(tx, 1)
assert.Nil(t, err)
env.blockHeight = env.blockHeight + 1
env.blockTime = env.blockTime + 20
env.difficulty = env.difficulty + 1
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
receipt, err = exec.Exec(tx, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
receiptData = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
t.Log(receiptData.Ty)
set, err = exec.ExecLocal(tx, receiptData, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
orderID9 := common.ToHex(tx.Hash())
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})
assert.Nil(t, err)
tx, err = types.FormatTx(cfg, et.ExchangeX, tx)
assert.Nil(t, err)
tx, err = signTx(tx, PrivKeyD)
assert.Nil(t, err)
err = e.CheckTx(tx, 1)
assert.Nil(t, err)
env.blockHeight = env.blockHeight + 1
env.blockTime = env.blockTime + 20
env.difficulty = env.difficulty + 1
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
receipt, err = exec.Exec(tx, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
receiptData = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err = exec.ExecLocal(tx, receiptData, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
orderID10 := common.ToHex(tx.Hash())
//根据订单号,查询订单详情
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID7}))
if err != nil {
t.Error(err)
}
reply = msg.(*et.Order)
assert.Equal(t, int32(et.Completed), reply.Status)
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID8}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply = msg.(*et.Order)
assert.Equal(t, int32(et.Completed), reply.Status)
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID9}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply = msg.(*et.Order)
assert.Equal(t, int32(et.Ordered), reply.Status)
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID10}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply = msg.(*et.Order)
assert.Equal(t, int32(et.Ordered), reply.Status)
acc = accD1.LoadExecAccount(string(Nodes[3]), execAddr)
t.Log(acc)
acc = accC.LoadExecAccount(string(Nodes[2]), execAddr)
assert.Equal(t, 80*types.Coin, acc.Balance)
t.Log(acc)
}
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
......
......@@ -273,6 +273,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
}
//单笔交易最多撮合100笔历史订单,最大可撮合得深度,系统得自我防护
//迭代已有挂单价格
for {
if count > et.MaxCount {
break
......@@ -281,6 +282,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
if err == types.ErrNotFound {
break
}
//elog.Info("matchLimitOrder.QueryMarketDepth", "marketList", marketDepthList)
for _, marketDepth := range marketDepthList.List {
if count > et.MaxCount {
break
......@@ -293,6 +295,8 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
if payload.Op == et.OpSell && marketDepth.Price < payload.GetPrice() {
continue
}
//根据价格进行迭代
for {
orderIDs, err := findOrderIDListByPrice(a.localDB, payload.GetLeftAsset(), payload.GetRightAsset(), marketDepth.Price, a.OpSwap(payload.Op), et.ListASC, index)
if err == types.ErrNotFound {
continue
......@@ -307,6 +311,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
if matchorder.Addr == a.fromaddr {
continue
}
//TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生
if matchorder.GetBalance() >= or.GetBalance() {
if payload.Op == et.OpSell {
......@@ -387,6 +392,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
return receipts, nil
}
if payload.Op == et.OpSell {
elog.Info("matchLimitOrder.findOrderByOrderID========", "order", matchorder)
//转移冻结资产
receipt, err := rightAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.Price))
if err != nil {
......@@ -398,7 +404,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
//解冻成交部分 多余资金
if payload.Price < matchorder.GetLimitOrder().Price {
receipt, err := rightAccountDB.ExecActive(matchorder.Addr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), matchorder.GetLimitOrder().Price-payload.Price))
receipt, err := rightAccountDB.ExecActive(matchorder.Addr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), matchorder.GetLimitOrder().Price-payload.Price))
if err != nil {
elog.Error("matchLimitOrder.ExecActive", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), matchorder.GetLimitOrder().Price-payload.Price), "err", err.Error())
return nil, err
......@@ -417,6 +423,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
kvs = append(kvs, receipt.KV...)
}
if payload.Op == et.OpBuy {
elog.Info("matchLimitOrder.findOrderByOrderID++++++", "order", matchorder)
//转移冻结资产
receipt, err := leftAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), matchorder.GetLimitOrder().Price))
if err != nil {
......@@ -459,6 +466,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
}
index = orderIDs[len(orderIDs)-1].Index
}
}
//查询数据不满足5条说明没有了,跳出循环
if len(marketDepthList.List) < int(et.Count) {
......
......@@ -91,6 +91,10 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
markDepth.Op = op
markDepth.Amount = receipt.Order.Balance
} else {
markDepth.Price = price
markDepth.LeftAsset = left
markDepth.RightAsset = right
markDepth.Op = op
markDepth.Amount = markDepth.Amount + receipt.Order.Balance
}
......@@ -103,7 +107,7 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
if len(receipt.MatchOrders) > 0 {
//撮合交易更新
cache :=make(map[float64]int64)
cache := make(map[float64]int64)
for i, matchOrder := range receipt.MatchOrders {
if matchOrder.Status == exchangetypes.Completed {
// 删除原有状态orderID
......@@ -115,17 +119,21 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
//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)})})
}
executed :=cache[matchOrder.GetLimitOrder().Price]
executed=executed+matchOrder.Executed
cache[matchOrder.GetLimitOrder().Price]=executed
executed := cache[matchOrder.GetLimitOrder().Price]
executed = executed + matchOrder.Executed
cache[matchOrder.GetLimitOrder().Price] = executed
}
//更改匹配市场深度
for pr,executed :=range cache{
for pr, executed := range cache {
var matchDepth exchangetypes.MarketDepth
err = findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), pr), &matchDepth)
if err == types.ErrNotFound {
continue
} else {
matchDepth.Price = pr
matchDepth.LeftAsset = left
matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op)
matchDepth.Amount = matchDepth.Amount - executed
}
//marketDepth
......@@ -152,7 +160,7 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
//calcCompletedOrderKey
kvs = append(kvs, &types.KeyValue{Key: calcCompletedOrderKey(left, right, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})})
cache :=make(map[float64]int64)
cache := make(map[float64]int64)
if len(receipt.MatchOrders) > 0 {
//撮合交易更新
for i, matchOrder := range receipt.MatchOrders {
......@@ -167,17 +175,21 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
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)})})
}
executed :=cache[matchOrder.GetLimitOrder().Price]
executed=executed+matchOrder.Executed
cache[matchOrder.GetLimitOrder().Price]=executed
executed := cache[matchOrder.GetLimitOrder().Price]
executed = executed + matchOrder.Executed
cache[matchOrder.GetLimitOrder().Price] = executed
}
//更改match市场深度
for pr,executed :=range cache{
for pr, executed := range cache {
var matchDepth exchangetypes.MarketDepth
err := findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), pr), &matchDepth)
if err == types.ErrNotFound {
continue
} else {
matchDepth.Price = pr
matchDepth.LeftAsset = left
matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op)
matchDepth.Amount = matchDepth.Amount - executed
}
//marketDepth
......
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