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

add tx rules

parent 5be5ce58
...@@ -69,7 +69,7 @@ func (e *exchange) CheckTx(tx *types.Transaction, index int) error { ...@@ -69,7 +69,7 @@ func (e *exchange) CheckTx(tx *types.Transaction, index int) error {
if !CheckPrice(price) { if !CheckPrice(price) {
return exchangetypes.ErrAssetPrice return exchangetypes.ErrAssetPrice
} }
if !types.CheckAmount(amount) { if !CheckAmount(amount) {
return exchangetypes.ErrAssetAmount return exchangetypes.ErrAssetAmount
} }
if !CheckOp(op) { if !CheckOp(op) {
...@@ -82,6 +82,11 @@ func (e *exchange) CheckTx(tx *types.Transaction, index int) error { ...@@ -82,6 +82,11 @@ func (e *exchange) CheckTx(tx *types.Transaction, index int) error {
return nil return nil
} }
//ExecutorOrder Exec 的时候 同时执行 ExecLocal
func (e *exchange) ExecutorOrder() int64 {
return drivers.ExecLocalSameTime
}
// GetPayloadValue get payload value // GetPayloadValue get payload value
func (e *exchange) GetPayloadValue() types.Message { func (e *exchange) GetPayloadValue() types.Message {
return &exchangetypes.ExchangeAction{} return &exchangetypes.ExchangeAction{}
......
...@@ -87,7 +87,7 @@ func TestExchange(t *testing.T) { ...@@ -87,7 +87,7 @@ func TestExchange(t *testing.T) {
accC1, _ := account.NewAccountDB(cfg, "paracross", "token.CCNY", stateDB) accC1, _ := account.NewAccountDB(cfg, "paracross", "token.CCNY", stateDB)
accC1.SaveExecAccount(execAddr, &accountC) accC1.SaveExecAccount(execAddr, &accountC)
accD1, _ := account.NewAccountDB(cfg, "token", "para", stateDB) accD1, _ := account.NewAccountDB(cfg, "token", "CCNY", stateDB)
accD1.SaveExecAccount(execAddr, &accountD) accD1.SaveExecAccount(execAddr, &accountD)
env := execEnv{ env := execEnv{
...@@ -439,6 +439,94 @@ func TestExchange(t *testing.T) { ...@@ -439,6 +439,94 @@ func TestExchange(t *testing.T) {
reply2 = msg.(*et.OrderList) reply2 = msg.(*et.OrderList)
t.Log(reply2) t.Log(reply2)
assert.Equal(t, 2, len(reply2.List)) assert.Equal(t, 2, len(reply2.List))
//低于市场价得卖单测试
// 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)
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)
}
orderID6 := common.ToHex(tx.Hash())
//根据订单号,查询订单详情
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID6}))
if err != nil {
t.Error(err)
}
t.Log(msg)
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})
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}
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)
}
orderID7 := common.ToHex(tx.Hash())
//根据订单号,查询订单详情
msg, err = exec.Query(et.FuncNameQueryOrder, types.Encode(&et.QueryOrder{OrderID: orderID6}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply = msg.(*et.Order)
acc = accD1.LoadExecAccount(string(Nodes[2]), execAddr)
t.Log(acc)
//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)
} }
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) { func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
......
This diff is collapsed.
...@@ -103,11 +103,11 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -103,11 +103,11 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
if len(receipt.MatchOrders) > 0 { if len(receipt.MatchOrders) > 0 {
//撮合交易更新 //撮合交易更新
var balance 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
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, matchOrder.GetLimitOrder().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
...@@ -115,30 +115,27 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -115,30 +115,27 @@ 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)})})
} }
if matchOrder.Status == exchangetypes.Ordered { executed :=cache[matchOrder.GetLimitOrder().Price]
//只需统一更改市场深度状态,其他不需要处理 executed=executed+matchOrder.Executed
balance = balance + matchOrder.Balance cache[matchOrder.GetLimitOrder().Price]=executed
}
} }
//更改匹配市场深度 //更改匹配市场深度
for pr,executed :=range cache{
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), pr), &matchDepth)
if err == types.ErrNotFound { if err == types.ErrNotFound {
matchDepth.Price = price continue
matchDepth.LeftAsset = left
matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op)
matchDepth.Amount = balance
} else { } else {
matchDepth.Amount = matchDepth.Amount - receipt.Order.Executed matchDepth.Amount = matchDepth.Amount - 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 { if matchDepth.Amount <= 0 {
//删除 //删除
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: nil}) kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: nil})
} }
} }
}
return return
case exchangetypes.Completed: case exchangetypes.Completed:
left := receipt.GetOrder().GetLimitOrder().GetLeftAsset() left := receipt.GetOrder().GetLimitOrder().GetLeftAsset()
...@@ -155,9 +152,9 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -155,9 +152,9 @@ 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)
if len(receipt.MatchOrders) > 0 { if len(receipt.MatchOrders) > 0 {
//撮合交易更新 //撮合交易更新
var balance 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
...@@ -170,30 +167,27 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t ...@@ -170,30 +167,27 @@ 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)})})
} }
if matchOrder.Status == exchangetypes.Ordered { executed :=cache[matchOrder.GetLimitOrder().Price]
//只需统一更改市场深度状态,其他不需要处理 executed=executed+matchOrder.Executed
balance = balance + matchOrder.Balance cache[matchOrder.GetLimitOrder().Price]=executed
}
} }
//更改match市场深度 //更改match市场深度
for pr,executed :=range cache{
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), pr), &matchDepth)
if err == types.ErrNotFound { if err == types.ErrNotFound {
matchDepth.Price = price continue
matchDepth.LeftAsset = left
matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op)
matchDepth.Amount = balance
} else { } else {
matchDepth.Amount = matchDepth.Amount - receipt.Order.Executed matchDepth.Amount = matchDepth.Amount - 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 { if matchDepth.Amount <= 0 {
//删除 //删除
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: nil}) kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: nil})
} }
} }
}
return return
case exchangetypes.Revoked: case exchangetypes.Revoked:
//只有状态时ordered状态的订单才能被撤回 //只有状态时ordered状态的订单才能被撤回
......
...@@ -55,10 +55,12 @@ const ( ...@@ -55,10 +55,12 @@ const (
ListSeek = int32(2) ListSeek = int32(2)
) )
//单次list还回条数
const ( const (
//单次list还回条数
Count = int32(5) Count = int32(5)
MaxCount = int32(20) //系统最大撮合深度
MaxCount = 100
) )
var ( var (
......
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