Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
link33
plugin
Commits
a3f2a08e
Commit
a3f2a08e
authored
Dec 13, 2019
by
harrylee
Committed by
vipwzw
Dec 26, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add tx rules
parent
5be5ce58
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
213 additions
and
57 deletions
+213
-57
exchange.go
plugin/dapp/exchange/executor/exchange.go
+6
-1
exchange_test.go
plugin/dapp/exchange/executor/exchange_test.go
+89
-1
exchangedb.go
plugin/dapp/exchange/executor/exchangedb.go
+93
-26
exec_local.go
plugin/dapp/exchange/executor/exec_local.go
+21
-27
exchange.go
plugin/dapp/exchange/types/exchange.go
+4
-2
No files found.
plugin/dapp/exchange/executor/exchange.go
View file @
a3f2a08e
...
...
@@ -69,7 +69,7 @@ func (e *exchange) CheckTx(tx *types.Transaction, index int) error {
if
!
CheckPrice
(
price
)
{
return
exchangetypes
.
ErrAssetPrice
}
if
!
types
.
CheckAmount
(
amount
)
{
if
!
CheckAmount
(
amount
)
{
return
exchangetypes
.
ErrAssetAmount
}
if
!
CheckOp
(
op
)
{
...
...
@@ -82,6 +82,11 @@ func (e *exchange) CheckTx(tx *types.Transaction, index int) error {
return
nil
}
//ExecutorOrder Exec 的时候 同时执行 ExecLocal
func
(
e
*
exchange
)
ExecutorOrder
()
int64
{
return
drivers
.
ExecLocalSameTime
}
// GetPayloadValue get payload value
func
(
e
*
exchange
)
GetPayloadValue
()
types
.
Message
{
return
&
exchangetypes
.
ExchangeAction
{}
...
...
plugin/dapp/exchange/executor/exchange_test.go
View file @
a3f2a08e
...
...
@@ -87,7 +87,7 @@ func TestExchange(t *testing.T) {
accC1
,
_
:=
account
.
NewAccountDB
(
cfg
,
"paracross"
,
"token.CCNY"
,
stateDB
)
accC1
.
SaveExecAccount
(
execAddr
,
&
accountC
)
accD1
,
_
:=
account
.
NewAccountDB
(
cfg
,
"token"
,
"
para
"
,
stateDB
)
accD1
,
_
:=
account
.
NewAccountDB
(
cfg
,
"token"
,
"
CCNY
"
,
stateDB
)
accD1
.
SaveExecAccount
(
execAddr
,
&
accountD
)
env
:=
execEnv
{
...
...
@@ -439,6 +439,94 @@ func TestExchange(t *testing.T) {
reply2
=
msg
.
(
*
et
.
OrderList
)
t
.
Log
(
reply2
)
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
)
{
...
...
plugin/dapp/exchange/executor/exchangedb.go
View file @
a3f2a08e
...
...
@@ -85,6 +85,14 @@ func CheckCount(count int32) bool {
return
count
<=
20
&&
count
>=
0
}
//最小交易1e8
func
CheckAmount
(
amount
int64
)
bool
{
if
amount
<
types
.
Coin
||
amount
>=
types
.
MaxCoin
{
return
false
}
return
true
}
func
CheckDirection
(
direction
int32
)
bool
{
if
direction
==
et
.
ListASC
||
direction
==
et
.
ListDESC
{
return
true
...
...
@@ -117,7 +125,7 @@ func (a *Action) LimitOrder(payload *et.LimitOrder) (*types.Receipt, error) {
if
!
CheckExchangeAsset
(
leftAsset
,
rightAsset
)
{
return
nil
,
et
.
ErrAsset
}
if
!
types
.
CheckAmount
(
payload
.
GetAmount
())
{
if
!
CheckAmount
(
payload
.
GetAmount
())
{
return
nil
,
et
.
ErrAssetAmount
}
if
!
CheckPrice
(
payload
.
GetPrice
())
{
...
...
@@ -236,10 +244,17 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
}
//撮合交易逻辑方法
// 规则:
//1.买单高于市场价,按价格由低往高撮合。
//2.卖单低于市场价,按价格由高往低进行撮合。
//3.价格相同按先进先出的原则进行撮合
//4.买家获利得原则
func
(
a
*
Action
)
matchLimitOrder
(
payload
*
et
.
LimitOrder
,
leftAccountDB
,
rightAccountDB
*
account
.
DB
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
var
kvs
[]
*
types
.
KeyValue
var
index
int64
var
price
float64
var
count
int
or
:=
&
et
.
Order
{
OrderID
:
common
.
ToHex
(
a
.
txhash
),
...
...
@@ -257,15 +272,30 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
Index
:
a
.
GetIndex
(),
}
//按先进先出的原则进行撮合
//单笔交易最多撮合100笔历史订单,最大可撮合得深度,系统得自我防护
for
i
:=
0
;
i
<
20
;
i
++
{
orderIDs
,
err
:=
findOrderIDListByPrice
(
a
.
localDB
,
payload
.
GetLeftAsset
(),
payload
.
GetRightAsset
(),
payload
.
GetPrice
(),
a
.
OpSwap
(
payload
.
Op
),
et
.
ListASC
,
index
)
for
{
if
count
>
et
.
MaxCount
{
break
}
marketDepthList
,
err
:=
QueryMarketDepth
(
a
.
localDB
,
payload
.
GetLeftAsset
(),
payload
.
GetRightAsset
(),
a
.
OpSwap
(
payload
.
Op
),
price
,
et
.
Count
)
if
err
==
types
.
ErrNotFound
{
break
}
if
err
!=
nil
{
return
nil
,
err
for
_
,
marketDepth
:=
range
marketDepthList
.
List
{
if
count
>
et
.
MaxCount
{
break
}
// 卖单价大于买单价
if
payload
.
Op
==
et
.
OpBuy
&&
marketDepth
.
Price
>
payload
.
GetPrice
()
{
continue
}
// 买单价小于卖单价
if
payload
.
Op
==
et
.
OpSell
&&
marketDepth
.
Price
<
payload
.
GetPrice
()
{
continue
}
orderIDs
,
err
:=
findOrderIDListByPrice
(
a
.
localDB
,
payload
.
GetLeftAsset
(),
payload
.
GetRightAsset
(),
marketDepth
.
Price
,
a
.
OpSwap
(
payload
.
Op
),
et
.
ListASC
,
index
)
if
err
==
types
.
ErrNotFound
{
continue
}
for
_
,
orderID
:=
range
orderIDs
{
matchorder
,
err
:=
findOrderByOrderID
(
a
.
statedb
,
orderID
.
ID
)
...
...
@@ -281,17 +311,28 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
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
()
))
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
.
GetPrice
()
),
"err"
,
err
.
Error
())
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
.
GetPrice
()
))
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
.
GetPrice
()
),
"err"
,
err
.
Error
())
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
...
)
...
...
@@ -299,17 +340,17 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
}
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
(),
matchorder
.
GetLimitOrder
()
.
Price
))
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
())
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
(),
payload
.
GetPrice
()
))
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
(),
payload
.
GetPrice
()
),
"err"
,
err
.
Error
())
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
...
)
...
...
@@ -324,7 +365,8 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
return
et
.
Completed
}(
matchorder
.
GetBalance
(),
or
.
GetBalance
())
matchorder
.
Balance
=
matchorder
.
GetBalance
()
-
or
.
GetBalance
()
matchorder
.
Executed
=
matchorder
.
Executed
+
or
.
GetBalance
()
//记录本次成交得量
matchorder
.
Executed
=
or
.
GetBalance
()
a
.
updateStateDBCache
(
matchorder
)
kvs
=
append
(
kvs
,
a
.
GetKVSet
(
matchorder
)
...
)
...
...
@@ -346,17 +388,29 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
}
if
payload
.
Op
==
et
.
OpSell
{
//转移冻结资产
receipt
,
err
:=
rightAccountDB
.
ExecTransferFrozen
(
matchorder
.
Addr
,
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorder
.
GetBalance
(),
payload
.
GetPrice
()))
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.ExecTransferFrozen"
,
"addr"
,
matchorder
.
Addr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorder
.
GetBalance
(),
payload
.
GetPrice
()
),
"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
}
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
()
))
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
.
GetPrice
()
),
"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
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
...
...
@@ -364,21 +418,22 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
}
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
(),
matchorder
.
GetLimitOrder
()
.
Price
))
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
())
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
(),
payload
.
GetPrice
()
))
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
(),
payload
.
GetPrice
()
),
"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
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
}
//涉及赋值先后顺序,不可颠倒
or
.
Balance
=
or
.
Balance
-
matchorder
.
Balance
...
...
@@ -387,7 +442,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
a
.
updateStateDBCache
(
or
)
// match receiptorder
matchorder
.
Executed
=
matchorder
.
Executed
+
matchorder
.
GetBalance
()
matchorder
.
Executed
=
matchorder
.
Balance
matchorder
.
Status
=
et
.
Completed
matchorder
.
Balance
=
0
a
.
updateStateDBCache
(
matchorder
)
...
...
@@ -395,7 +450,8 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
re
.
Order
=
or
re
.
MatchOrders
=
append
(
re
.
MatchOrders
,
matchorder
)
}
//撮合深度计数
count
=
count
+
1
}
//查询数据不满足5条说明没有了,跳出循环
if
len
(
orderIDs
)
<
int
(
et
.
Count
)
{
...
...
@@ -404,6 +460,13 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
index
=
orderIDs
[
len
(
orderIDs
)
-
1
]
.
Index
}
//查询数据不满足5条说明没有了,跳出循环
if
len
(
marketDepthList
.
List
)
<
int
(
et
.
Count
)
{
break
}
price
=
marketDepthList
.
List
[
len
(
marketDepthList
.
List
)
-
1
]
.
Price
}
//冻结剩余未成交的资金
if
payload
.
Op
==
et
.
OpBuy
{
receipt
,
err
:=
rightAccountDB
.
ExecFrozen
(
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
et
.
OpBuy
,
or
.
Balance
,
payload
.
Price
))
...
...
@@ -490,7 +553,7 @@ func Direction(op int32) int32 {
}
//这里price当作索引来用,首次查询不需要填值
func
QueryMarketDepth
(
localdb
dbm
.
Lister
,
left
,
right
*
et
.
Asset
,
op
int32
,
price
float64
,
count
int32
)
(
types
.
Message
,
error
)
{
func
QueryMarketDepth
(
localdb
dbm
.
Lister
,
left
,
right
*
et
.
Asset
,
op
int32
,
price
float64
,
count
int32
)
(
*
et
.
MarketDepthList
,
error
)
{
prefix
:=
calcMarketDepthPrefix
(
left
,
right
,
op
)
key
:=
calcMarketDepthKey
(
left
,
right
,
op
,
price
)
var
values
[][]
byte
...
...
@@ -548,6 +611,8 @@ func QueryCompletedOrderList(localdb dbm.Lister, statedb dbm.KV, left, right *et
}
//替换索引index
order
.
Index
=
orderID
.
Index
//替换已经成交得量
order
.
Executed
=
order
.
GetLimitOrder
()
.
Amount
-
order
.
Balance
orderList
.
List
=
append
(
orderList
.
List
,
order
)
}
...
...
@@ -586,6 +651,8 @@ func QueryOrderList(localdb dbm.Lister, statedb dbm.KV, addr string, status, cou
}
//替换索引index
order
.
Index
=
orderID
.
Index
//替换已经成交得量
order
.
Executed
=
order
.
GetLimitOrder
()
.
Amount
-
order
.
Balance
orderList
.
List
=
append
(
orderList
.
List
,
order
)
}
return
&
orderList
,
nil
...
...
plugin/dapp/exchange/executor/exec_local.go
View file @
a3f2a08e
...
...
@@ -103,11 +103,11 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
if
len
(
receipt
.
MatchOrders
)
>
0
{
//撮合交易更新
var
balance
int64
cache
:=
make
(
map
[
float64
]
int64
)
for
i
,
matchOrder
:=
range
receipt
.
MatchOrders
{
if
matchOrder
.
Status
==
exchangetypes
.
Completed
{
// 删除原有状态orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthOrderKey
(
left
,
right
,
matchOrder
.
GetLimitOrder
()
.
Op
,
p
rice
,
matchOrder
.
Index
),
Value
:
nil
})
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthOrderKey
(
left
,
right
,
matchOrder
.
GetLimitOrder
()
.
Op
,
matchOrder
.
GetLimitOrder
()
.
P
rice
,
matchOrder
.
Index
),
Value
:
nil
})
//删除原有状态orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Ordered
,
matchOrder
.
Addr
,
matchOrder
.
Index
),
Value
:
nil
})
//更新状态为已完成,索引index,改为当前的index
...
...
@@ -115,30 +115,27 @@ 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
)})})
}
if
matchOrder
.
Status
==
exchangetypes
.
Ordered
{
//只需统一更改市场深度状态,其他不需要处理
balance
=
balance
+
matchOrder
.
Balance
}
executed
:=
cache
[
matchOrder
.
GetLimitOrder
()
.
Price
]
executed
=
executed
+
matchOrder
.
Executed
cache
[
matchOrder
.
GetLimitOrder
()
.
Price
]
=
executed
}
//更改匹配市场深度
for
pr
,
executed
:=
range
cache
{
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
{
matchDepth
.
Price
=
price
matchDepth
.
LeftAsset
=
left
matchDepth
.
RightAsset
=
right
matchDepth
.
Op
=
OpSwap
(
op
)
matchDepth
.
Amount
=
balance
continue
}
else
{
matchDepth
.
Amount
=
matchDepth
.
Amount
-
receipt
.
Order
.
E
xecuted
matchDepth
.
Amount
=
matchDepth
.
Amount
-
e
xecuted
}
//marketDepth
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
})
}
}
}
return
case
exchangetypes
.
Completed
:
left
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetLeftAsset
()
...
...
@@ -155,9 +152,9 @@ 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
)
if
len
(
receipt
.
MatchOrders
)
>
0
{
//撮合交易更新
var
balance
int64
for
i
,
matchOrder
:=
range
receipt
.
MatchOrders
{
if
matchOrder
.
Status
==
exchangetypes
.
Completed
{
// 删除原有状态orderID
...
...
@@ -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
)})})
}
if
matchOrder
.
Status
==
exchangetypes
.
Ordered
{
//只需统一更改市场深度状态,其他不需要处理
balance
=
balance
+
matchOrder
.
Balance
}
executed
:=
cache
[
matchOrder
.
GetLimitOrder
()
.
Price
]
executed
=
executed
+
matchOrder
.
Executed
cache
[
matchOrder
.
GetLimitOrder
()
.
Price
]
=
executed
}
//更改match市场深度
for
pr
,
executed
:=
range
cache
{
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
{
matchDepth
.
Price
=
price
matchDepth
.
LeftAsset
=
left
matchDepth
.
RightAsset
=
right
matchDepth
.
Op
=
OpSwap
(
op
)
matchDepth
.
Amount
=
balance
continue
}
else
{
matchDepth
.
Amount
=
matchDepth
.
Amount
-
receipt
.
Order
.
E
xecuted
matchDepth
.
Amount
=
matchDepth
.
Amount
-
e
xecuted
}
//marketDepth
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
})
}
}
}
return
case
exchangetypes
.
Revoked
:
//只有状态时ordered状态的订单才能被撤回
...
...
plugin/dapp/exchange/types/exchange.go
View file @
a3f2a08e
...
...
@@ -55,10 +55,12 @@ const (
ListSeek
=
int32
(
2
)
)
//单次list还回条数
const
(
//单次list还回条数
Count
=
int32
(
5
)
MaxCount
=
int32
(
20
)
//系统最大撮合深度
MaxCount
=
100
)
var
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment