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) { ...@@ -63,7 +63,7 @@ func TestExchange(t *testing.T) {
Addr: string(Nodes[3]), Addr: string(Nodes[3]),
} }
execAddr := address.ExecAddress(et.ExchangeX) execAddr := address.ExecAddress(et.ExchangeX)
stateDB, _ := dbm.NewGoMemDB("1", "2", 1000) stateDB, _ := dbm.NewGoMemDB("1", "2", 5000)
_, _, kvdb := util.CreateTestDB() _, _, kvdb := util.CreateTestDB()
accA, _ := account.NewAccountDB(cfg, "coins", "bty", stateDB) accA, _ := account.NewAccountDB(cfg, "coins", "bty", stateDB)
...@@ -440,10 +440,14 @@ func TestExchange(t *testing.T) { ...@@ -440,10 +440,14 @@ func TestExchange(t *testing.T) {
t.Log(reply2) t.Log(reply2)
assert.Equal(t, 2, len(reply2.List)) 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"}, 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}) RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: 4, Amount: 5 * types.Coin, Op: et.OpBuy})
assert.Nil(t, err) assert.Nil(t, err)
...@@ -478,7 +482,7 @@ func TestExchange(t *testing.T) { ...@@ -478,7 +482,7 @@ func TestExchange(t *testing.T) {
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
t.Log(msg) t.Log(msg)
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: 3, Amount: 10 * types.Coin, Op: et.OpSell}) RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: 3, Amount: 10 * types.Coin, Op: et.OpSell})
...@@ -501,6 +505,7 @@ func TestExchange(t *testing.T) { ...@@ -501,6 +505,7 @@ func TestExchange(t *testing.T) {
stateDB.Set(kv.Key, kv.Value) stateDB.Set(kv.Key, kv.Value)
} }
receiptData = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs} receiptData = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
t.Log(receiptData.Ty)
set, err = exec.ExecLocal(tx, receiptData, int(1)) set, err = exec.ExecLocal(tx, receiptData, int(1))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
...@@ -517,16 +522,147 @@ func TestExchange(t *testing.T) { ...@@ -517,16 +522,147 @@ func TestExchange(t *testing.T) {
} }
t.Log(msg) t.Log(msg)
reply = msg.(*et.Order) 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) t.Log(acc)
//assert.Equal(t, int32(et.Completed), reply.Status) assert.Equal(t, 85*types.Coin, acc.Balance)
acc = accC.LoadExecAccount(string(Nodes[2]), execAddr)
t.Log(acc)
// 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})) msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID7}))
if err != nil { if err != nil {
t.Error(err) 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) t.Log(msg)
reply = msg.(*et.Order) reply = msg.(*et.Order)
assert.Equal(t, int32(et.Ordered), reply.Status) 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) { func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
......
...@@ -273,6 +273,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -273,6 +273,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
} }
//单笔交易最多撮合100笔历史订单,最大可撮合得深度,系统得自我防护 //单笔交易最多撮合100笔历史订单,最大可撮合得深度,系统得自我防护
//迭代已有挂单价格
for { for {
if count > et.MaxCount { if count > et.MaxCount {
break break
...@@ -281,6 +282,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -281,6 +282,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
if err == types.ErrNotFound { if err == types.ErrNotFound {
break break
} }
//elog.Info("matchLimitOrder.QueryMarketDepth", "marketList", marketDepthList)
for _, marketDepth := range marketDepthList.List { for _, marketDepth := range marketDepthList.List {
if count > et.MaxCount { if count > et.MaxCount {
break break
...@@ -293,35 +295,116 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -293,35 +295,116 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
if payload.Op == et.OpSell && marketDepth.Price < payload.GetPrice() { if payload.Op == et.OpSell && marketDepth.Price < payload.GetPrice() {
continue continue
} }
orderIDs, err := findOrderIDListByPrice(a.localDB, payload.GetLeftAsset(), payload.GetRightAsset(), marketDepth.Price, a.OpSwap(payload.Op), et.ListASC, index) //根据价格进行迭代
if err == types.ErrNotFound { for {
continue orderIDs, err := findOrderIDListByPrice(a.localDB, payload.GetLeftAsset(), payload.GetRightAsset(), marketDepth.Price, a.OpSwap(payload.Op), et.ListASC, index)
} if err == types.ErrNotFound {
for _, orderID := range orderIDs {
matchorder, err := findOrderByOrderID(a.statedb, orderID.ID)
if err != nil {
elog.Warn("matchLimitOrder.findOrderByOrderID", "order", "err", err.Error())
continue
}
//同地址不能交易
if matchorder.Addr == a.fromaddr {
continue continue
} }
//TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生 for _, orderID := range orderIDs {
if matchorder.GetBalance() >= or.GetBalance() { matchorder, err := findOrderByOrderID(a.statedb, orderID.ID)
if err != nil {
elog.Warn("matchLimitOrder.findOrderByOrderID", "order", "err", err.Error())
continue
}
//同地址不能交易
if matchorder.Addr == a.fromaddr {
continue
}
//TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生
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.Price))
if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), payload.Price), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
//解冻多余资金
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))
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
}
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.Price))
if err != nil {
elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(payload.Op, or.GetBalance(), payload.Price), "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(), matchorder.GetLimitOrder().Price))
if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), matchorder.GetLimitOrder().Price), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
//将达成交易的相应资产结算
receipt, err = rightAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, a.calcActualCost(payload.Op, or.GetBalance(), matchorder.GetLimitOrder().Price))
if err != nil {
elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(payload.Op, or.GetBalance(), matchorder.GetLimitOrder().Price), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
}
// match receiptorder,涉及赋值先手顺序,代码顺序不可变
matchorder.Status = func(a, b int64) int32 {
if a > b {
return et.Ordered
}
return et.Completed
}(matchorder.GetBalance(), or.GetBalance())
matchorder.Balance = matchorder.GetBalance() - or.GetBalance()
//记录本次成交得量
matchorder.Executed = or.GetBalance()
a.updateStateDBCache(matchorder)
kvs = append(kvs, a.GetKVSet(matchorder)...)
or.Executed = or.Executed + or.GetBalance()
or.Status = et.Completed
or.Balance = 0
//update receipt order
re.Order = or
re.MatchOrders = append(re.MatchOrders, matchorder)
a.updateStateDBCache(or)
kvs = append(kvs, a.GetKVSet(or)...)
//statedb 更新
receiptlog := &types.ReceiptLog{Ty: et.TyLimitOrderLog, Log: types.Encode(re)}
logs = append(logs, receiptlog)
receipts := &types.Receipt{Ty: types.ExecOk, KV: kvs, Logs: logs}
return receipts, nil
}
if payload.Op == et.OpSell { 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, or.GetBalance(), payload.Price)) receipt, err := rightAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.Price))
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), payload.Price), "err", err.Error()) elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.Price), "err", err.Error())
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
//解冻多余资金 //解冻成交部分 多余资金
if payload.Price < matchorder.GetLimitOrder().Price { 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 { 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()) 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 return nil, err
...@@ -329,135 +412,60 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -329,135 +412,60 @@ 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...)
} }
//将达成交易的相应资产结算 //将达成交易的相应资产结算
receipt, err = leftAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, a.calcActualCost(payload.Op, or.GetBalance(), payload.Price)) receipt, err = leftAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, a.calcActualCost(payload.Op, matchorder.GetBalance(), payload.Price))
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(payload.Op, or.GetBalance(), payload.Price), "err", err.Error()) elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(payload.Op, matchorder.GetBalance(), payload.Price), "err", err.Error())
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
} }
if payload.Op == et.OpBuy { 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, or.GetBalance(), matchorder.GetLimitOrder().Price)) receipt, err := leftAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), matchorder.GetLimitOrder().Price))
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, or.GetBalance(), matchorder.GetLimitOrder().Price), "err", err.Error()) elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), matchorder.GetLimitOrder().Price), "err", err.Error())
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
//将达成交易的相应资产结算 //将达成交易的相应资产结算
receipt, err = rightAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, a.calcActualCost(payload.Op, or.GetBalance(), matchorder.GetLimitOrder().Price)) receipt, err = rightAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, a.calcActualCost(payload.Op, matchorder.GetBalance(), matchorder.GetLimitOrder().Price))
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(payload.Op, or.GetBalance(), matchorder.GetLimitOrder().Price), "err", err.Error()) elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(payload.Op, matchorder.GetBalance(), matchorder.GetLimitOrder().Price), "err", err.Error())
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
} }
// match receiptorder,涉及赋值先手顺序,代码顺序不可变 //涉及赋值先后顺序,不可颠倒
matchorder.Status = func(a, b int64) int32 { or.Balance = or.Balance - matchorder.Balance
if a > b { or.Executed = or.Executed + matchorder.Balance
return et.Ordered or.Status = et.Ordered
} a.updateStateDBCache(or)
return et.Completed
}(matchorder.GetBalance(), or.GetBalance())
matchorder.Balance = matchorder.GetBalance() - or.GetBalance()
//记录本次成交得量
matchorder.Executed = or.GetBalance()
// match receiptorder
matchorder.Executed = matchorder.Balance
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.Executed = or.Executed + or.GetBalance()
or.Status = et.Completed
or.Balance = 0
//update receipt order
re.Order = or re.Order = or
re.MatchOrders = append(re.MatchOrders, matchorder) re.MatchOrders = append(re.MatchOrders, matchorder)
//撮合深度计数
a.updateStateDBCache(or) count = count + 1
kvs = append(kvs, a.GetKVSet(or)...)
//statedb 更新
receiptlog := &types.ReceiptLog{Ty: et.TyLimitOrderLog, Log: types.Encode(re)}
logs = append(logs, receiptlog)
receipts := &types.Receipt{Ty: types.ExecOk, KV: kvs, Logs: logs}
return receipts, nil
}
if payload.Op == et.OpSell {
//转移冻结资产
receipt, err := rightAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.Price))
if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), payload.Price), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
//解冻成交部分 多余资金
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))
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
}
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.Price))
if err != nil {
elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(payload.Op, matchorder.GetBalance(), payload.Price), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
} }
if payload.Op == et.OpBuy { //查询数据不满足5条说明没有了,跳出循环
//转移冻结资产 if len(orderIDs) < int(et.Count) {
receipt, err := leftAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), matchorder.GetLimitOrder().Price)) break
if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "execaddr", a.execaddr, "amount", a.calcActualCost(matchorder.GetLimitOrder().Op, matchorder.GetBalance(), matchorder.GetLimitOrder().Price), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
//将达成交易的相应资产结算
receipt, err = rightAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, a.calcActualCost(payload.Op, matchorder.GetBalance(), matchorder.GetLimitOrder().Price))
if err != nil {
elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", a.calcActualCost(payload.Op, matchorder.GetBalance(), matchorder.GetLimitOrder().Price), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
} }
index = orderIDs[len(orderIDs)-1].Index
//涉及赋值先后顺序,不可颠倒
or.Balance = or.Balance - matchorder.Balance
or.Executed = or.Executed + matchorder.Balance
or.Status = et.Ordered
a.updateStateDBCache(or)
// match receiptorder
matchorder.Executed = matchorder.Balance
matchorder.Status = et.Completed
matchorder.Balance = 0
a.updateStateDBCache(matchorder)
kvs = append(kvs, a.GetKVSet(matchorder)...)
re.Order = or
re.MatchOrders = append(re.MatchOrders, matchorder)
//撮合深度计数
count = count + 1
}
//查询数据不满足5条说明没有了,跳出循环
if len(orderIDs) < int(et.Count) {
break
} }
index = orderIDs[len(orderIDs)-1].Index
} }
//查询数据不满足5条说明没有了,跳出循环 //查询数据不满足5条说明没有了,跳出循环
......
...@@ -91,6 +91,10 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -91,6 +91,10 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
markDepth.Op = op markDepth.Op = op
markDepth.Amount = receipt.Order.Balance markDepth.Amount = receipt.Order.Balance
} else { } else {
markDepth.Price = price
markDepth.LeftAsset = left
markDepth.RightAsset = right
markDepth.Op = op
markDepth.Amount = markDepth.Amount + receipt.Order.Balance markDepth.Amount = markDepth.Amount + receipt.Order.Balance
} }
...@@ -103,7 +107,7 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -103,7 +107,7 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
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 == exchangetypes.Completed {
// 删除原有状态orderID // 删除原有状态orderID
...@@ -115,17 +119,21 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -115,17 +119,21 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
//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)})}) 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 := 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 exchangetypes.MarketDepth
err = findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), pr), &matchDepth) err = findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), pr), &matchDepth)
if err == types.ErrNotFound { if err == types.ErrNotFound {
continue continue
} else { } else {
matchDepth.Price = pr
matchDepth.LeftAsset = left
matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op)
matchDepth.Amount = matchDepth.Amount - executed matchDepth.Amount = matchDepth.Amount - executed
} }
//marketDepth //marketDepth
...@@ -152,7 +160,7 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -152,7 +160,7 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
//calcCompletedOrderKey //calcCompletedOrderKey
kvs = append(kvs, &types.KeyValue{Key: calcCompletedOrderKey(left, right, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})}) 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 { if len(receipt.MatchOrders) > 0 {
//撮合交易更新 //撮合交易更新
for i, matchOrder := range receipt.MatchOrders { for i, matchOrder := range receipt.MatchOrders {
...@@ -167,17 +175,21 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -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)})}) 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 := cache[matchOrder.GetLimitOrder().Price]
executed=executed+matchOrder.Executed executed = executed + matchOrder.Executed
cache[matchOrder.GetLimitOrder().Price]=executed cache[matchOrder.GetLimitOrder().Price] = executed
} }
//更改match市场深度 //更改match市场深度
for pr,executed :=range cache{ for pr, executed := range cache {
var matchDepth exchangetypes.MarketDepth var matchDepth exchangetypes.MarketDepth
err := findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), pr), &matchDepth) err := findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), pr), &matchDepth)
if err == types.ErrNotFound { if err == types.ErrNotFound {
continue continue
} else { } else {
matchDepth.Price = pr
matchDepth.LeftAsset = left
matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op)
matchDepth.Amount = matchDepth.Amount - executed matchDepth.Amount = matchDepth.Amount - executed
} }
//marketDepth //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