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
ad7f9e41
Commit
ad7f9e41
authored
Dec 16, 2019
by
harrylee
Committed by
vipwzw
Dec 26, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add some test
parent
a3f2a08e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
289 additions
and
133 deletions
+289
-133
exchange_test.go
plugin/dapp/exchange/executor/exchange_test.go
+142
-6
exchangedb.go
plugin/dapp/exchange/executor/exchangedb.go
+124
-116
exec_local.go
plugin/dapp/exchange/executor/exec_local.go
+23
-11
No files found.
plugin/dapp/exchange/executor/exchange_test.go
View file @
ad7f9e41
...
...
@@ -63,7 +63,7 @@ func TestExchange(t *testing.T) {
Addr
:
string
(
Nodes
[
3
]),
}
execAddr
:=
address
.
ExecAddress
(
et
.
ExchangeX
)
stateDB
,
_
:=
dbm
.
NewGoMemDB
(
"1"
,
"2"
,
1
000
)
stateDB
,
_
:=
dbm
.
NewGoMemDB
(
"1"
,
"2"
,
5
000
)
_
,
_
,
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
)
...
...
@@ -478,7 +482,7 @@ func TestExchange(t *testing.T) {
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
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
})
...
...
@@ -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, 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
}))
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
)
{
...
...
plugin/dapp/exchange/executor/exchangedb.go
View file @
ad7f9e41
...
...
@@ -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,35 +295,116 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
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
)
if
err
!=
nil
{
elog
.
Warn
(
"matchLimitOrder.findOrderByOrderID"
,
"order"
,
"err"
,
err
.
Error
())
continue
}
//同地址不能交易
if
matchorder
.
Addr
==
a
.
fromaddr
{
//根据价格进行迭代
for
{
orderIDs
,
err
:=
findOrderIDListByPrice
(
a
.
localDB
,
payload
.
GetLeftAsset
(),
payload
.
GetRightAsset
(),
marketDepth
.
Price
,
a
.
OpSwap
(
payload
.
Op
),
et
.
ListASC
,
index
)
if
err
==
types
.
ErrNotFound
{
continue
}
//TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生
if
matchorder
.
GetBalance
()
>=
or
.
GetBalance
()
{
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
}
//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
{
elog
.
Info
(
"matchLimitOrder.findOrderByOrderID========"
,
"order"
,
matchorder
)
//转移冻结资产
receipt
,
err
:=
rightAccountDB
.
ExecTransferFrozen
(
matchorder
.
Addr
,
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
o
r
.
GetBalance
(),
payload
.
Price
))
receipt
,
err
:=
rightAccountDB
.
ExecTransferFrozen
(
matchorder
.
Addr
,
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorde
r
.
GetBalance
(),
payload
.
Price
))
if
err
!=
nil
{
elog
.
Error
(
"matchLimitOrder.ExecTransferFrozen"
,
"addr"
,
matchorder
.
Addr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
o
r
.
GetBalance
(),
payload
.
Price
),
"err"
,
err
.
Error
())
elog
.
Error
(
"matchLimitOrder.ExecTransferFrozen"
,
"addr"
,
matchorder
.
Addr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorde
r
.
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
,
o
r
.
GetBalance
(),
matchorder
.
GetLimitOrder
()
.
Price
-
payload
.
Price
))
receipt
,
err
:=
rightAccountDB
.
ExecActive
(
matchorder
.
Addr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorde
r
.
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
...
...
@@ -329,135 +412,60 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
logs
=
append
(
logs
,
receipt
.
Logs
...
)
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
}
//将达成交易的相应资产结算
receipt
,
err
=
leftAccountDB
.
ExecTransfer
(
a
.
fromaddr
,
matchorder
.
Addr
,
a
.
execaddr
,
a
.
calcActualCost
(
payload
.
Op
,
o
r
.
GetBalance
(),
payload
.
Price
))
receipt
,
err
=
leftAccountDB
.
ExecTransfer
(
a
.
fromaddr
,
matchorder
.
Addr
,
a
.
execaddr
,
a
.
calcActualCost
(
payload
.
Op
,
matchorde
r
.
GetBalance
(),
payload
.
Price
))
if
err
!=
nil
{
elog
.
Error
(
"matchLimitOrder.ExecTransfer"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
payload
.
Op
,
o
r
.
GetBalance
(),
payload
.
Price
),
"err"
,
err
.
Error
())
elog
.
Error
(
"matchLimitOrder.ExecTransfer"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
payload
.
Op
,
matchorde
r
.
GetBalance
(),
payload
.
Price
),
"err"
,
err
.
Error
())
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
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
,
o
r
.
GetBalance
(),
matchorder
.
GetLimitOrder
()
.
Price
))
receipt
,
err
:=
leftAccountDB
.
ExecTransferFrozen
(
matchorder
.
Addr
,
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorde
r
.
GetBalance
(),
matchorder
.
GetLimitOrder
()
.
Price
))
if
err
!=
nil
{
elog
.
Error
(
"matchLimitOrder.ExecTransferFrozen"
,
"addr"
,
matchorder
.
Addr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
o
r
.
GetBalance
(),
matchorder
.
GetLimitOrder
()
.
Price
),
"err"
,
err
.
Error
())
elog
.
Error
(
"matchLimitOrder.ExecTransferFrozen"
,
"addr"
,
matchorder
.
Addr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorde
r
.
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
,
o
r
.
GetBalance
(),
matchorder
.
GetLimitOrder
()
.
Price
))
receipt
,
err
=
rightAccountDB
.
ExecTransfer
(
a
.
fromaddr
,
matchorder
.
Addr
,
a
.
execaddr
,
a
.
calcActualCost
(
payload
.
Op
,
matchorde
r
.
GetBalance
(),
matchorder
.
GetLimitOrder
()
.
Price
))
if
err
!=
nil
{
elog
.
Error
(
"matchLimitOrder.ExecTransfer"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
payload
.
Op
,
o
r
.
GetBalance
(),
matchorder
.
GetLimitOrder
()
.
Price
),
"err"
,
err
.
Error
())
elog
.
Error
(
"matchLimitOrder.ExecTransfer"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
payload
.
Op
,
matchorde
r
.
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
()
//涉及赋值先后顺序,不可颠倒
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
)
...
)
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
{
//转移冻结资产
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
...
)
//撮合深度计数
count
=
count
+
1
}
if
payload
.
Op
==
et
.
OpBuy
{
//转移冻结资产
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
(),
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
...
)
//查询数据不满足5条说明没有了,跳出循环
if
len
(
orderIDs
)
<
int
(
et
.
Count
)
{
break
}
//涉及赋值先后顺序,不可颠倒
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
}
index
=
orderIDs
[
len
(
orderIDs
)
-
1
]
.
Index
}
//查询数据不满足5条说明没有了,跳出循环
...
...
plugin/dapp/exchange/executor/exec_local.go
View file @
ad7f9e41
...
...
@@ -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
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
...
...
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