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
5d8922a2
Commit
5d8922a2
authored
Dec 09, 2019
by
harrylee
Committed by
vipwzw
Dec 26, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add exchange_test.go
parent
ef710316
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
690 additions
and
122 deletions
+690
-122
exchange_test.go
plugin/dapp/exchange/executor/exchange_test.go
+457
-5
exchangedb.go
plugin/dapp/exchange/executor/exchangedb.go
+88
-46
exec.go
plugin/dapp/exchange/executor/exec.go
+7
-9
exec_local.go
plugin/dapp/exchange/executor/exec_local.go
+57
-12
kv.go
plugin/dapp/exchange/executor/kv.go
+6
-4
query.go
plugin/dapp/exchange/executor/query.go
+0
-3
exchange.proto
plugin/dapp/exchange/proto/exchange.proto
+1
-1
exchange.pb.go
plugin/dapp/exchange/types/exchange.pb.go
+74
-42
No files found.
plugin/dapp/exchange/executor/exchange_test.go
View file @
5d8922a2
...
@@ -2,13 +2,466 @@ package executor
...
@@ -2,13 +2,466 @@ package executor
import
(
import
(
"testing"
"testing"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/queue"
et
"github.com/33cn/plugin/plugin/dapp/exchange/types"
"github.com/stretchr/testify/assert"
)
type
execEnv
struct
{
blockTime
int64
blockHeight
int64
difficulty
uint64
}
var
(
PrivKeyA
=
"0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
// 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
PrivKeyB
=
"0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4"
// 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR
PrivKeyC
=
"0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115"
// 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k
PrivKeyD
=
"0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71"
// 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs
Nodes
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
)
)
func
TestExchange
(
t
*
testing
.
T
)
{
cfg
:=
types
.
NewChain33Config
(
types
.
GetDefaultCfgstring
())
cfg
.
SetTitleOnlyForTest
(
"chain33"
)
Init
(
et
.
ExchangeX
,
cfg
,
nil
)
total
:=
100
*
types
.
Coin
accountA
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
0
]),
}
accountB
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
1
]),
}
accountC
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
2
]),
}
accountD
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
3
]),
}
execAddr
:=
address
.
ExecAddress
(
et
.
ExchangeX
)
stateDB
,
_
:=
dbm
.
NewGoMemDB
(
"1"
,
"2"
,
1000
)
_
,
_
,
kvdb
:=
util
.
CreateTestDB
()
accA
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accA
.
SaveExecAccount
(
execAddr
,
&
accountA
)
accB
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accB
.
SaveExecAccount
(
execAddr
,
&
accountB
)
accC
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accC
.
SaveExecAccount
(
execAddr
,
&
accountC
)
accD
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accD
.
SaveExecAccount
(
execAddr
,
&
accountD
)
accA1
,
_
:=
account
.
NewAccountDB
(
cfg
,
"token"
,
"CCNY"
,
stateDB
)
accA1
.
SaveExecAccount
(
execAddr
,
&
accountA
)
accB1
,
_
:=
account
.
NewAccountDB
(
cfg
,
"paracross"
,
"coins.bty"
,
stateDB
)
accB1
.
SaveExecAccount
(
execAddr
,
&
accountB
)
accC1
,
_
:=
account
.
NewAccountDB
(
cfg
,
"paracross"
,
"token.CCNY"
,
stateDB
)
accC1
.
SaveExecAccount
(
execAddr
,
&
accountC
)
accD1
,
_
:=
account
.
NewAccountDB
(
cfg
,
"token"
,
"para"
,
stateDB
)
accD1
.
SaveExecAccount
(
execAddr
,
&
accountD
)
env
:=
execEnv
{
10
,
cfg
.
GetDappFork
(
et
.
ExchangeX
,
"Enable"
),
1539918074
,
}
// orderlimit bty:CCNY 买bty
ety
:=
types
.
LoadExecutorType
(
et
.
ExchangeX
)
tx
,
err
:=
ety
.
Create
(
"LimitOrder"
,
&
et
.
LimitOrder
{
LeftAsset
:
&
et
.
Asset
{
Symbol
:
"bty"
,
Execer
:
"coins"
},
RightAsset
:
&
et
.
Asset
{
Execer
:
"token"
,
Symbol
:
"CCNY"
},
Price
:
4
,
Amount
:
10
*
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
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
exec
:=
newExchange
()
e
:=
exec
.
(
*
exchange
)
err
=
e
.
CheckTx
(
tx
,
1
)
assert
.
Nil
(
t
,
err
)
q
:=
queue
.
New
(
"channel"
)
q
.
SetConfig
(
cfg
)
api
,
_
:=
client
.
New
(
q
.
Client
(),
nil
)
exec
.
SetAPI
(
api
)
exec
.
SetStateDB
(
stateDB
)
exec
.
SetLocalDB
(
kvdb
)
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
)
}
orderID1
:=
common
.
ToHex
(
tx
.
Hash
())
//根据订单号,查询订单详情
msg
,
err
:=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID1
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
reply
:=
msg
.
(
*
et
.
Order
)
t
.
Log
(
reply
)
assert
.
Equal
(
t
,
int32
(
et
.
Ordered
),
reply
.
Status
)
assert
.
Equal
(
t
,
10
*
types
.
Coin
,
reply
.
GetBalance
())
//查看账户余额
acc
:=
accA1
.
LoadExecAccount
(
string
(
Nodes
[
0
]),
execAddr
)
t
.
Log
(
acc
)
//根据op查询市场深度
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryMarketDepth
,
types
.
Encode
(
&
et
.
QueryMarketDepth
{
LeftAsset
:
&
et
.
Asset
{
Symbol
:
"bty"
,
Execer
:
"coins"
},
RightAsset
:
&
et
.
Asset
{
Execer
:
"token"
,
Symbol
:
"CCNY"
},
Op
:
et
.
OpBuy
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply1
:=
msg
.
(
*
et
.
MarketDepthList
)
assert
.
Equal
(
t
,
10
*
types
.
Coin
,
reply1
.
List
[
0
]
.
GetAmount
())
//根据状态和地址查询
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Ordered
,
Address
:
string
(
Nodes
[
0
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply2
:=
msg
.
(
*
et
.
OrderList
)
assert
.
Equal
(
t
,
orderID1
,
reply2
.
List
[
0
]
.
OrderID
)
// orderlimit bty:CCNY 卖bty
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
,
PrivKeyB
)
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
)
}
orderID2
:=
common
.
ToHex
(
tx
.
Hash
())
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID1
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
//订单1的状态应该还是ordered
reply
=
msg
.
(
*
et
.
Order
)
assert
.
Equal
(
t
,
int32
(
et
.
Ordered
),
reply
.
Status
)
t
.
Log
(
reply
)
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID2
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
reply
=
msg
.
(
*
et
.
Order
)
assert
.
Equal
(
t
,
int32
(
et
.
Completed
),
reply
.
Status
)
//根据op查询市场深度
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryMarketDepth
,
types
.
Encode
(
&
et
.
QueryMarketDepth
{
LeftAsset
:
&
et
.
Asset
{
Symbol
:
"bty"
,
Execer
:
"coins"
},
RightAsset
:
&
et
.
Asset
{
Execer
:
"token"
,
Symbol
:
"CCNY"
},
Op
:
et
.
OpBuy
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply1
=
msg
.
(
*
et
.
MarketDepthList
)
t
.
Log
(
reply1
.
List
)
//市场深度应该改变
assert
.
Equal
(
t
,
5
*
types
.
Coin
,
reply1
.
List
[
0
]
.
GetAmount
())
//QueryCompletedOrderList
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryCompletedOrderList
,
types
.
Encode
(
&
et
.
QueryCompletedOrderList
{
LeftAsset
:
&
et
.
Asset
{
Symbol
:
"bty"
,
Execer
:
"coins"
},
RightAsset
:
&
et
.
Asset
{
Execer
:
"token"
,
Symbol
:
"CCNY"
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
reply2
=
msg
.
(
*
et
.
OrderList
)
assert
.
Equal
(
t
,
orderID2
,
reply2
.
List
[
0
]
.
OrderID
)
//撤回之前的订单
// orderlimit bty:CCNY
tx
,
err
=
ety
.
Create
(
"RevokeOrder"
,
&
et
.
RevokeOrder
{
OrderID
:
orderID1
})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
et
.
ExchangeX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
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
)
}
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID1
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
reply
=
msg
.
(
*
et
.
Order
)
assert
.
Equal
(
t
,
int32
(
et
.
Revoked
),
reply
.
Status
)
t
.
Log
(
reply
)
//根据op查询市场深度
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryMarketDepth
,
types
.
Encode
(
&
et
.
QueryMarketDepth
{
LeftAsset
:
&
et
.
Asset
{
Symbol
:
"bty"
,
Execer
:
"coins"
},
RightAsset
:
&
et
.
Asset
{
Execer
:
"token"
,
Symbol
:
"CCNY"
},
Op
:
et
.
OpBuy
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
reply1
=
msg
.
(
*
et
.
MarketDepthList
)
t
.
Log
(
reply1
.
GetList
())
t
.
Log
(
len
(
reply1
.
GetList
()))
//反向测试
// orderlimit bty:CCNY 卖bty
tx
,
err
=
ety
.
Create
(
"LimitOrder"
,
&
et
.
LimitOrder
{
LeftAsset
:
&
et
.
Asset
{
Symbol
:
"bty"
,
Execer
:
"coins"
},
RightAsset
:
&
et
.
Asset
{
Execer
:
"paracross"
,
Symbol
:
"coins.bty"
},
Price
:
0.5
,
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
,
PrivKeyA
)
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
)
}
orderID3
:=
common
.
ToHex
(
tx
.
Hash
())
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID3
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
//订单1的状态应该还是ordered
reply
=
msg
.
(
*
et
.
Order
)
assert
.
Equal
(
t
,
int32
(
et
.
Ordered
),
reply
.
Status
)
t
.
Log
(
reply
)
tx
,
err
=
ety
.
Create
(
"LimitOrder"
,
&
et
.
LimitOrder
{
LeftAsset
:
&
et
.
Asset
{
Symbol
:
"bty"
,
Execer
:
"coins"
},
RightAsset
:
&
et
.
Asset
{
Execer
:
"paracross"
,
Symbol
:
"coins.bty"
},
Price
:
0.5
,
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
,
PrivKeyA
)
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
)
}
orderID4
:=
common
.
ToHex
(
tx
.
Hash
())
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID4
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
//订单1的状态应该还是ordered
reply
=
msg
.
(
*
et
.
Order
)
assert
.
Equal
(
t
,
int32
(
et
.
Ordered
),
reply
.
Status
)
t
.
Log
(
reply
)
//根据op查询市场深度
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryMarketDepth
,
types
.
Encode
(
&
et
.
QueryMarketDepth
{
LeftAsset
:
&
et
.
Asset
{
Symbol
:
"bty"
,
Execer
:
"coins"
},
RightAsset
:
&
et
.
Asset
{
Execer
:
"paracross"
,
Symbol
:
"coins.bty"
},
Op
:
et
.
OpSell
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
reply1
=
msg
.
(
*
et
.
MarketDepthList
)
t
.
Log
(
reply1
.
List
)
//市场深度应该改变
assert
.
Equal
(
t
,
20
*
types
.
Coin
,
reply1
.
List
[
0
]
.
GetAmount
())
//根据状态和地址查询
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Ordered
,
Address
:
string
(
Nodes
[
0
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
reply2
=
msg
.
(
*
et
.
OrderList
)
t
.
Log
(
reply2
)
//默认倒序查询
assert
.
Equal
(
t
,
orderID3
,
reply2
.
List
[
1
]
.
OrderID
)
assert
.
Equal
(
t
,
orderID4
,
reply2
.
List
[
0
]
.
OrderID
)
tx
,
err
=
ety
.
Create
(
"LimitOrder"
,
&
et
.
LimitOrder
{
LeftAsset
:
&
et
.
Asset
{
Symbol
:
"bty"
,
Execer
:
"coins"
},
RightAsset
:
&
et
.
Asset
{
Execer
:
"paracross"
,
Symbol
:
"coins.bty"
},
Price
:
0.5
,
Amount
:
20
*
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
,
PrivKeyB
)
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
)
}
orderID5
:=
common
.
ToHex
(
tx
.
Hash
())
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID5
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
//订单1的状态应该还是ordered
reply
=
msg
.
(
*
et
.
Order
)
assert
.
Equal
(
t
,
int32
(
et
.
Completed
),
reply
.
Status
)
//根据op查询市场深度
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryMarketDepth
,
types
.
Encode
(
&
et
.
QueryMarketDepth
{
LeftAsset
:
&
et
.
Asset
{
Symbol
:
"bty"
,
Execer
:
"coins"
},
RightAsset
:
&
et
.
Asset
{
Execer
:
"paracross"
,
Symbol
:
"coins.bty"
},
Op
:
et
.
OpSell
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
reply1
=
msg
.
(
*
et
.
MarketDepthList
)
t
.
Log
(
reply1
.
List
)
}
func
signTx
(
tx
*
types
.
Transaction
,
hexPrivKey
string
)
(
*
types
.
Transaction
,
error
)
{
signType
:=
types
.
SECP256K1
c
,
err
:=
crypto
.
New
(
types
.
GetSignName
(
""
,
signType
))
if
err
!=
nil
{
return
tx
,
err
}
bytes
,
err
:=
common
.
FromHex
(
hexPrivKey
[
:
])
if
err
!=
nil
{
return
tx
,
err
}
privKey
,
err
:=
c
.
PrivKeyFromBytes
(
bytes
)
if
err
!=
nil
{
return
tx
,
err
}
tx
.
Sign
(
int32
(
signType
),
privKey
)
return
tx
,
nil
}
func
TestTruncate
(
t
*
testing
.
T
)
{
func
TestTruncate
(
t
*
testing
.
T
)
{
a
:=
float32
(
1.00000212000000000001
)
a
:=
float32
(
1.00000212000000000001
)
b
:=
float32
(
0.34567
)
b
:=
float32
(
0.34567
)
c
:=
float32
(
1234
)
c
:=
float32
(
1234
)
t
.
Log
(
Truncate
(
a
))
t
.
Log
(
Truncate
(
a
))
t
.
Log
(
Truncate
(
b
))
t
.
Log
(
Truncate
(
b
))
t
.
Log
(
Truncate
(
c
))
t
.
Log
(
Truncate
(
c
))
}
}
\ No newline at end of file
func
TestCheckPrice
(
t
*
testing
.
T
)
{
t
.
Log
(
CheckPrice
(
0.25
))
}
plugin/dapp/exchange/executor/exchangedb.go
View file @
5d8922a2
...
@@ -35,7 +35,8 @@ func NewAction(e *exchange, tx *types.Transaction, index int) *Action {
...
@@ -35,7 +35,8 @@ func NewAction(e *exchange, tx *types.Transaction, index int) *Action {
//GetIndex get index
//GetIndex get index
func
(
a
*
Action
)
GetIndex
()
int64
{
func
(
a
*
Action
)
GetIndex
()
int64
{
return
a
.
height
*
types
.
MaxTxsPerBlock
+
int64
(
a
.
index
)
//扩容4个0,用于匹配多个matchorder索引时使用
return
(
a
.
height
*
types
.
MaxTxsPerBlock
+
int64
(
a
.
index
))
*
1e4
}
}
//GetKVSet get kv set
//GetKVSet get kv set
...
@@ -66,9 +67,9 @@ func (a *Action) calcActualCost(op int32, amount int64, price float32) int64 {
...
@@ -66,9 +67,9 @@ func (a *Action) calcActualCost(op int32, amount int64, price float32) int64 {
return
amount
return
amount
}
}
//price 精度允许范围小数点后面7位数,
整数是
1e8
//price 精度允许范围小数点后面7位数,
0<price<
1e8
func
CheckPrice
(
price
float32
)
bool
{
func
CheckPrice
(
price
float32
)
bool
{
if
(
Truncate
(
price
)
>
1e8
)
||
(
Truncate
(
price
)
*
float32
(
1e8
)
<=
0
)
{
if
(
Truncate
(
price
)
>
=
1e8
)
||
(
Truncate
(
price
)
*
float32
(
1e8
)
<=
0
)
{
return
false
return
false
}
}
return
true
return
true
...
@@ -122,7 +123,7 @@ func (a *Action) LimitOrder(payload *et.LimitOrder) (*types.Receipt, error) {
...
@@ -122,7 +123,7 @@ func (a *Action) LimitOrder(payload *et.LimitOrder) (*types.Receipt, error) {
if
!
types
.
CheckAmount
(
payload
.
GetAmount
())
{
if
!
types
.
CheckAmount
(
payload
.
GetAmount
())
{
return
nil
,
et
.
ErrAssetAmount
return
nil
,
et
.
ErrAssetAmount
}
}
if
CheckPrice
(
payload
.
GetPrice
())
{
if
!
CheckPrice
(
payload
.
GetPrice
())
{
return
nil
,
et
.
ErrAssetPrice
return
nil
,
et
.
ErrAssetPrice
}
}
if
!
CheckOp
(
payload
.
GetOp
())
{
if
!
CheckOp
(
payload
.
GetOp
())
{
...
@@ -188,7 +189,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
...
@@ -188,7 +189,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
amount
:=
int64
(
float32
(
balance
)
*
price
)
amount
:=
a
.
calcActualCost
(
et
.
OpBuy
,
balance
,
price
)
rightAccount
:=
rightAssetDB
.
LoadExecAccount
(
a
.
fromaddr
,
a
.
execaddr
)
rightAccount
:=
rightAssetDB
.
LoadExecAccount
(
a
.
fromaddr
,
a
.
execaddr
)
if
rightAccount
.
Frozen
<
amount
{
if
rightAccount
.
Frozen
<
amount
{
elog
.
Error
(
"RevokeOrder.BalanceCheck"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
amount
,
"err"
,
et
.
ErrAssetBalance
.
Error
())
elog
.
Error
(
"RevokeOrder.BalanceCheck"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
amount
,
"err"
,
et
.
ErrAssetBalance
.
Error
())
...
@@ -207,7 +208,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
...
@@ -207,7 +208,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
amount
:=
balance
amount
:=
a
.
calcActualCost
(
et
.
OpBuy
,
balance
,
price
)
leftAccount
:=
leftAssetDB
.
LoadExecAccount
(
a
.
fromaddr
,
a
.
execaddr
)
leftAccount
:=
leftAssetDB
.
LoadExecAccount
(
a
.
fromaddr
,
a
.
execaddr
)
if
leftAccount
.
Frozen
<
amount
{
if
leftAccount
.
Frozen
<
amount
{
elog
.
Error
(
"RevokeOrder.BalanceCheck"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
amount
,
"err"
,
et
.
ErrAssetBalance
.
Error
())
elog
.
Error
(
"RevokeOrder.BalanceCheck"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
amount
,
"err"
,
et
.
ErrAssetBalance
.
Error
())
...
@@ -281,25 +282,44 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
...
@@ -281,25 +282,44 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
}
}
//TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生
//TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生
if
matchorder
.
GetBalance
()
>=
or
.
GetBalance
()
{
if
matchorder
.
GetBalance
()
>=
or
.
GetBalance
()
{
//转移冻结资产
if
payload
.
Op
==
et
.
OpSell
{
receipt
,
err
:=
leftAccountDB
.
ExecTransferFrozen
(
matchorder
.
Addr
,
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
or
.
GetBalance
(),
payload
.
GetPrice
()))
//转移冻结资产
if
err
!=
nil
{
receipt
,
err
:=
rightAccountDB
.
ExecTransferFrozen
(
matchorder
.
Addr
,
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
or
.
GetBalance
(),
payload
.
GetPrice
()))
elog
.
Error
(
"matchLimitOrder.ExecTransferFrozen"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
or
.
GetBalance
(),
payload
.
GetPrice
()),
"err"
,
err
.
Error
())
if
err
!=
nil
{
return
nil
,
err
elog
.
Error
(
"matchLimitOrder.ExecTransferFrozen"
,
"addr"
,
matchorder
.
Addr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
or
.
GetBalance
(),
payload
.
GetPrice
()),
"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
()))
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
())
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
}
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
if
payload
.
Op
==
et
.
OpBuy
{
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
//转移冻结资产
//将达成交易的相应资产结算
receipt
,
err
:=
leftAccountDB
.
ExecTransferFrozen
(
matchorder
.
Addr
,
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
or
.
GetBalance
(),
payload
.
GetPrice
()))
receipt
,
err
=
rightAccountDB
.
ExecTransfer
(
a
.
fromaddr
,
matchorder
.
Addr
,
a
.
execaddr
,
a
.
calcActualCost
(
payload
.
Op
,
or
.
GetBalance
(),
payload
.
GetPrice
()))
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
.
GetPrice
()),
"err"
,
err
.
Error
())
elog
.
Error
(
"matchLimitOrder.ExecTransfer"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
payload
.
Op
,
or
.
GetBalance
(),
payload
.
GetPrice
()),
"err"
,
err
.
Error
())
return
nil
,
err
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
()))
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
())
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
}
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
// match receiptorder,涉及赋值先手顺序,代码顺序不可变
// match receiptorder
matchorder
.
Balance
=
matchorder
.
GetBalance
()
-
or
.
GetBalance
()
matchorder
.
Executed
=
matchorder
.
Executed
+
or
.
GetBalance
()
matchorder
.
Status
=
func
(
a
,
b
int64
)
int32
{
matchorder
.
Status
=
func
(
a
,
b
int64
)
int32
{
if
a
>
b
{
if
a
>
b
{
return
et
.
Ordered
return
et
.
Ordered
...
@@ -307,12 +327,15 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
...
@@ -307,12 +327,15 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
return
et
.
Completed
return
et
.
Completed
}
}
}(
matchorder
.
GetBalance
(),
or
.
GetBalance
())
}(
matchorder
.
GetBalance
(),
or
.
GetBalance
())
matchorder
.
Balance
=
matchorder
.
GetBalance
()
-
or
.
GetBalance
()
matchorder
.
Executed
=
matchorder
.
Executed
+
or
.
GetBalance
()
a
.
updateStateDBCache
(
matchorder
)
a
.
updateStateDBCache
(
matchorder
)
kvs
=
append
(
kvs
,
a
.
GetKVSet
(
matchorder
)
...
)
kvs
=
append
(
kvs
,
a
.
GetKVSet
(
matchorder
)
...
)
or
.
Balance
=
0
or
.
Executed
=
or
.
Executed
+
or
.
GetBalance
()
or
.
Executed
=
or
.
Executed
+
or
.
GetBalance
()
or
.
Status
=
et
.
Completed
or
.
Status
=
et
.
Completed
or
.
Balance
=
0
//update receipt order
//update receipt order
re
.
Order
=
or
re
.
Order
=
or
re
.
MatchOrders
=
append
(
re
.
MatchOrders
,
matchorder
)
re
.
MatchOrders
=
append
(
re
.
MatchOrders
,
matchorder
)
...
@@ -325,39 +348,58 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
...
@@ -325,39 +348,58 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
receipts
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kvs
,
Logs
:
logs
}
receipts
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kvs
,
Logs
:
logs
}
return
receipts
,
nil
return
receipts
,
nil
}
else
{
}
else
{
//转移冻结资产
if
payload
.
Op
==
et
.
OpSell
{
receipt
,
err
:=
leftAccountDB
.
ExecTransferFrozen
(
matchorder
.
Addr
,
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorder
.
GetBalance
(),
payload
.
GetPrice
()))
//转移冻结资产
if
err
!=
nil
{
receipt
,
err
:=
rightAccountDB
.
ExecTransferFrozen
(
matchorder
.
Addr
,
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorder
.
GetBalance
(),
payload
.
GetPrice
()))
elog
.
Error
(
"matchLimitOrder.ExecTransferFrozen"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorder
.
GetBalance
(),
payload
.
GetPrice
()),
"err"
,
err
.
Error
())
if
err
!=
nil
{
return
nil
,
err
elog
.
Error
(
"matchLimitOrder.ExecTransferFrozen"
,
"addr"
,
matchorder
.
Addr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorder
.
GetBalance
(),
payload
.
GetPrice
()),
"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
()))
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
())
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
}
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
if
payload
.
Op
==
et
.
OpBuy
{
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
//转移冻结资产
//将达成交易的相应资产结算
receipt
,
err
:=
leftAccountDB
.
ExecTransferFrozen
(
matchorder
.
Addr
,
a
.
fromaddr
,
a
.
execaddr
,
a
.
calcActualCost
(
matchorder
.
GetLimitOrder
()
.
Op
,
matchorder
.
GetBalance
(),
payload
.
GetPrice
()))
receipt
,
err
=
rightAccountDB
.
ExecTransfer
(
a
.
fromaddr
,
matchorder
.
Addr
,
a
.
execaddr
,
a
.
calcActualCost
(
payload
.
Op
,
matchorder
.
GetBalance
(),
payload
.
GetPrice
()))
if
err
!=
nil
{
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.ExecTransfer"
,
"addr"
,
a
.
fromaddr
,
"execaddr"
,
a
.
execaddr
,
"amount"
,
a
.
calcActualCost
(
payload
.
Op
,
matchorder
.
GetBalance
(),
payload
.
GetPrice
()),
"err"
,
err
.
Error
())
return
nil
,
err
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
()))
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
())
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
}
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
//涉及赋值先后顺序,不可颠倒
or
.
Balance
=
or
.
Balance
-
matchorder
.
Balance
or
.
Executed
=
or
.
Executed
+
matchorder
.
Balance
or
.
Status
=
et
.
Ordered
a
.
updateStateDBCache
(
or
)
// match receiptorder
// match receiptorder
matchorder
.
Balance
=
0
matchorder
.
Executed
=
matchorder
.
Executed
+
matchorder
.
GetBalance
()
matchorder
.
Executed
=
matchorder
.
Executed
+
matchorder
.
GetBalance
()
matchorder
.
Status
=
et
.
Completed
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
.
Balance
=
or
.
Balance
-
matchorder
.
Balance
or
.
Executed
=
or
.
Executed
+
matchorder
.
Balance
or
.
Status
=
et
.
Ordered
re
.
Order
=
or
re
.
Order
=
or
re
.
MatchOrders
=
append
(
re
.
MatchOrders
,
matchorder
)
re
.
MatchOrders
=
append
(
re
.
MatchOrders
,
matchorder
)
a
.
updateStateDBCache
(
or
)
}
}
}
}
//查询数据不满足5条说明没有了,跳出循环
//查询数据不满足5条说明没有了,跳出循环
...
...
plugin/dapp/exchange/executor/exec.go
View file @
5d8922a2
package
executor
package
executor
import
(
import
(
"fmt"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
exchangetypes
"github.com/33cn/plugin/plugin/dapp/exchange/types"
exchangetypes
"github.com/33cn/plugin/plugin/dapp/exchange/types"
)
)
...
@@ -11,19 +12,16 @@ import (
...
@@ -11,19 +12,16 @@ import (
*/
*/
func
(
e
*
exchange
)
Exec_LimitOrder
(
payload
*
exchangetypes
.
LimitOrder
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
func
(
e
*
exchange
)
Exec_LimitOrder
(
payload
*
exchangetypes
.
LimitOrder
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
var
receipt
*
types
.
Receipt
action
:=
NewAction
(
e
,
tx
,
index
)
//implement code
return
action
.
LimitOrder
(
payload
)
return
receipt
,
nil
}
}
func
(
e
*
exchange
)
Exec_MarketOrder
(
payload
*
exchangetypes
.
MarketOrder
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
func
(
e
*
exchange
)
Exec_MarketOrder
(
payload
*
exchangetypes
.
MarketOrder
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
var
receipt
*
types
.
Receipt
//TODO marketOrder
//implement code
return
nil
,
fmt
.
Errorf
(
"%s"
,
"not support MarketOrder.."
)
return
receipt
,
nil
}
}
func
(
e
*
exchange
)
Exec_RevokeOrder
(
payload
*
exchangetypes
.
RevokeOrder
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
func
(
e
*
exchange
)
Exec_RevokeOrder
(
payload
*
exchangetypes
.
RevokeOrder
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
var
receipt
*
types
.
Receipt
action
:=
NewAction
(
e
,
tx
,
index
)
//implement code
return
action
.
RevokeOrder
(
payload
)
return
receipt
,
nil
}
}
plugin/dapp/exchange/executor/exec_local.go
View file @
5d8922a2
...
@@ -30,13 +30,37 @@ func (e *exchange) ExecLocal_LimitOrder(payload *exchangetypes.LimitOrder, tx *t
...
@@ -30,13 +30,37 @@ func (e *exchange) ExecLocal_LimitOrder(payload *exchangetypes.LimitOrder, tx *t
func
(
e
*
exchange
)
ExecLocal_MarketOrder
(
payload
*
exchangetypes
.
MarketOrder
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
e
*
exchange
)
ExecLocal_MarketOrder
(
payload
*
exchangetypes
.
MarketOrder
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
if
receiptData
.
Ty
==
types
.
ExecOk
{
for
_
,
log
:=
range
receiptData
.
Logs
{
switch
log
.
Ty
{
case
exchangetypes
.
TyMarketOrderLog
:
receipt
:=
&
exchangetypes
.
ReceiptExchange
{}
if
err
:=
types
.
Decode
(
log
.
Log
,
receipt
);
err
!=
nil
{
return
nil
,
err
}
kv
:=
e
.
updateIndex
(
receipt
)
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kv
...
)
}
}
}
return
e
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
return
e
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
}
func
(
e
*
exchange
)
ExecLocal_RevokeOrder
(
payload
*
exchangetypes
.
RevokeOrder
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
e
*
exchange
)
ExecLocal_RevokeOrder
(
payload
*
exchangetypes
.
RevokeOrder
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
if
receiptData
.
Ty
==
types
.
ExecOk
{
for
_
,
log
:=
range
receiptData
.
Logs
{
switch
log
.
Ty
{
case
exchangetypes
.
TyRevokeOrderLog
:
receipt
:=
&
exchangetypes
.
ReceiptExchange
{}
if
err
:=
types
.
Decode
(
log
.
Log
,
receipt
);
err
!=
nil
{
return
nil
,
err
}
kv
:=
e
.
updateIndex
(
receipt
)
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kv
...
)
}
}
}
return
e
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
return
e
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
}
...
@@ -66,8 +90,10 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
...
@@ -66,8 +90,10 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
markDepth
.
RightAsset
=
right
markDepth
.
RightAsset
=
right
markDepth
.
Op
=
op
markDepth
.
Op
=
op
markDepth
.
Amount
=
receipt
.
Order
.
Balance
markDepth
.
Amount
=
receipt
.
Order
.
Balance
}
else
{
markDepth
.
Amount
=
markDepth
.
Amount
+
receipt
.
Order
.
Balance
}
}
markDepth
.
Amount
=
markDepth
.
Amount
+
receipt
.
Order
.
Balance
//marketDepth
//marketDepth
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
op
,
price
),
Value
:
types
.
Encode
(
&
markDepth
)})
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
op
,
price
),
Value
:
types
.
Encode
(
&
markDepth
)})
//orderID
//orderID
...
@@ -78,23 +104,23 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
...
@@ -78,23 +104,23 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
if
len
(
receipt
.
MatchOrders
)
>
0
{
if
len
(
receipt
.
MatchOrders
)
>
0
{
//撮合交易更新
//撮合交易更新
var
balance
int64
var
balance
int64
for
_
,
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
,
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
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Completed
,
matchOrder
.
Addr
,
index
),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
matchOrder
.
OrderID
,
Index
:
index
})})
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Completed
,
matchOrder
.
Addr
,
index
+
int64
(
i
+
1
)),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
matchOrder
.
OrderID
,
Index
:
index
+
int64
(
i
+
1
)
})})
//calcCompletedOrderKey
//calcCompletedOrderKey
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcCompletedOrderKey
(
left
,
right
,
index
),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
matchOrder
.
OrderID
,
Index
:
index
})})
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
{
if
matchOrder
.
Status
==
exchangetypes
.
Ordered
{
//只需统一更改市场深度状态,其他不需要处理
//只需统一更改市场深度状态,其他不需要处理
balance
=
balance
+
matchOrder
.
Balance
balance
=
balance
+
matchOrder
.
Balance
}
}
}
}
//更改市场深度
//更改
匹配
市场深度
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
),
price
),
&
matchDepth
)
if
err
==
types
.
ErrNotFound
{
if
err
==
types
.
ErrNotFound
{
...
@@ -103,10 +129,15 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
...
@@ -103,10 +129,15 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
matchDepth
.
RightAsset
=
right
matchDepth
.
RightAsset
=
right
matchDepth
.
Op
=
OpSwap
(
op
)
matchDepth
.
Op
=
OpSwap
(
op
)
matchDepth
.
Amount
=
balance
matchDepth
.
Amount
=
balance
}
else
{
matchDepth
.
Amount
=
matchDepth
.
Amount
-
receipt
.
Order
.
Executed
}
}
matchDepth
.
Amount
=
matchDepth
.
Amount
-
receipt
.
Order
.
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
{
//删除
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
OpSwap
(
op
),
price
),
Value
:
nil
})
}
}
}
return
return
case
exchangetypes
.
Completed
:
case
exchangetypes
.
Completed
:
...
@@ -121,19 +152,22 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
...
@@ -121,19 +152,22 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
//user orderID
//user orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Completed
,
addr
,
index
),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
oderID
,
Index
:
index
})})
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Completed
,
addr
,
index
),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
oderID
,
Index
:
index
})})
//calcCompletedOrderKey
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcCompletedOrderKey
(
left
,
right
,
index
),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
oderID
,
Index
:
index
})})
if
len
(
receipt
.
MatchOrders
)
>
0
{
if
len
(
receipt
.
MatchOrders
)
>
0
{
//撮合交易更新
//撮合交易更新
var
balance
int64
var
balance
int64
for
_
,
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
,
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
})
//更新状态为已完成,更新索引
//更新状态为已完成,更新索引
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Completed
,
matchOrder
.
Addr
,
index
),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
matchOrder
.
OrderID
,
Index
:
index
})})
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Completed
,
matchOrder
.
Addr
,
index
+
int64
(
i
+
1
)),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
matchOrder
.
OrderID
,
Index
:
index
+
int64
(
i
+
1
)
})})
//calcCompletedOrderKey
//calcCompletedOrderKey
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcCompletedOrderKey
(
left
,
right
,
index
),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
matchOrder
.
OrderID
,
Index
:
index
})})
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
{
if
matchOrder
.
Status
==
exchangetypes
.
Ordered
{
...
@@ -150,10 +184,15 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
...
@@ -150,10 +184,15 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
matchDepth
.
RightAsset
=
right
matchDepth
.
RightAsset
=
right
matchDepth
.
Op
=
OpSwap
(
op
)
matchDepth
.
Op
=
OpSwap
(
op
)
matchDepth
.
Amount
=
balance
matchDepth
.
Amount
=
balance
}
else
{
matchDepth
.
Amount
=
matchDepth
.
Amount
-
receipt
.
Order
.
Executed
}
}
matchDepth
.
Amount
=
matchDepth
.
Amount
-
receipt
.
Order
.
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
{
//删除
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
OpSwap
(
op
),
price
),
Value
:
nil
})
}
}
}
return
return
case
exchangetypes
.
Revoked
:
case
exchangetypes
.
Revoked
:
...
@@ -170,8 +209,14 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
...
@@ -170,8 +209,14 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
if
err
==
nil
{
if
err
==
nil
{
//marketDepth
//marketDepth
marketDepth
.
Amount
=
marketDepth
.
Amount
-
receipt
.
GetOrder
()
.
Balance
marketDepth
.
Amount
=
marketDepth
.
Amount
-
receipt
.
GetOrder
()
.
Balance
elog
.
Error
(
"revoked"
,
"recept.order.balance"
,
receipt
.
GetOrder
()
.
Balance
)
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
op
,
price
),
Value
:
types
.
Encode
(
&
marketDepth
)})
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
op
,
price
),
Value
:
types
.
Encode
(
&
marketDepth
)})
}
}
elog
.
Error
(
"revoked"
,
"marketDepth.Amount"
,
marketDepth
.
Amount
)
if
marketDepth
.
Amount
==
0
{
//删除
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
op
,
price
),
Value
:
nil
})
}
// 删除原有状态orderID
// 删除原有状态orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthOrderKey
(
left
,
right
,
op
,
price
,
receipt
.
GetOrder
()
.
Index
),
Value
:
nil
})
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthOrderKey
(
left
,
right
,
op
,
price
,
receipt
.
GetOrder
()
.
Index
),
Value
:
nil
})
//删除原有状态orderID
//删除原有状态orderID
...
...
plugin/dapp/exchange/executor/kv.go
View file @
5d8922a2
...
@@ -45,14 +45,15 @@ func calcMarketDepthOrderPrefix(left, right *types.Asset, op int32, price float3
...
@@ -45,14 +45,15 @@ func calcMarketDepthOrderPrefix(left, right *types.Asset, op int32, price float3
// localdb中存储市场挂单ID
// localdb中存储市场挂单ID
func
calcMarketDepthOrderKey
(
left
,
right
*
types
.
Asset
,
op
int32
,
price
float32
,
index
int64
)
[]
byte
{
func
calcMarketDepthOrderKey
(
left
,
right
*
types
.
Asset
,
op
int32
,
price
float32
,
index
int64
)
[]
byte
{
// 设置精度为1e8
// 设置精度为1e8
key
:=
fmt
.
Sprintf
(
"%s"
+
"order-%s-%s-%d:%016d:%0
18
d"
,
KeyPrefixLocalDB
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
op
,
int64
(
Truncate
(
price
)
*
float32
(
1e8
)),
index
)
key
:=
fmt
.
Sprintf
(
"%s"
+
"order-%s-%s-%d:%016d:%0
22
d"
,
KeyPrefixLocalDB
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
op
,
int64
(
Truncate
(
price
)
*
float32
(
1e8
)),
index
)
return
[]
byte
(
key
)
return
[]
byte
(
key
)
}
}
//最新已经成交的订单,这里状态固定都是完成状态,这个主要给外部使用,可以查询最新得成交信息
//最新已经成交的订单,这里状态固定都是完成状态,这个主要给外部使用,可以查询最新得成交信息,存在多个情况
//matchOrderIndex,是匹配order在数组中的index,这里预留4个0000,用来解决同一笔交易中存在key重复得情况,这样设计保证了key得唯一性
func
calcCompletedOrderKey
(
left
,
right
*
types
.
Asset
,
index
int64
)
[]
byte
{
func
calcCompletedOrderKey
(
left
,
right
*
types
.
Asset
,
index
int64
)
[]
byte
{
// 设置精度为1e8
// 设置精度为1e8
key
:=
fmt
.
Sprintf
(
"%s"
+
"completed-%s-%s-%d:%0
18
d"
,
KeyPrefixLocalDB
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
types
.
Completed
,
index
)
key
:=
fmt
.
Sprintf
(
"%s"
+
"completed-%s-%s-%d:%0
22
d"
,
KeyPrefixLocalDB
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
types
.
Completed
,
index
)
return
[]
byte
(
key
)
return
[]
byte
(
key
)
}
}
func
calcCompletedOrderPrefix
(
left
,
right
*
types
.
Asset
)
[]
byte
{
func
calcCompletedOrderPrefix
(
left
,
right
*
types
.
Asset
)
[]
byte
{
...
@@ -66,7 +67,8 @@ func calcUserOrderIDPrefix(status int32, addr string) []byte {
...
@@ -66,7 +67,8 @@ func calcUserOrderIDPrefix(status int32, addr string) []byte {
key
:=
fmt
.
Sprintf
(
"%s"
+
"addr:%s:%d:"
,
KeyPrefixLocalDB
,
addr
,
status
)
key
:=
fmt
.
Sprintf
(
"%s"
+
"addr:%s:%d:"
,
KeyPrefixLocalDB
,
addr
,
status
)
return
[]
byte
(
key
)
return
[]
byte
(
key
)
}
}
//matchOrderIndex,用来解决同一笔交易中存在key重复得情况,这样设计保证了key得唯一性
func
calcUserOrderIDKey
(
status
int32
,
addr
string
,
index
int64
)
[]
byte
{
func
calcUserOrderIDKey
(
status
int32
,
addr
string
,
index
int64
)
[]
byte
{
key
:=
fmt
.
Sprintf
(
"%s"
+
"addr:%s:%d:%0
18
d"
,
KeyPrefixLocalDB
,
addr
,
status
,
index
)
key
:=
fmt
.
Sprintf
(
"%s"
+
"addr:%s:%d:%0
22
d"
,
KeyPrefixLocalDB
,
addr
,
status
,
index
)
return
[]
byte
(
key
)
return
[]
byte
(
key
)
}
}
plugin/dapp/exchange/executor/query.go
View file @
5d8922a2
...
@@ -16,9 +16,6 @@ func (s *exchange) Query_QueryMarketDepth(in *et.QueryMarketDepth) (types.Messag
...
@@ -16,9 +16,6 @@ func (s *exchange) Query_QueryMarketDepth(in *et.QueryMarketDepth) (types.Messag
if
!
CheckExchangeAsset
(
in
.
LeftAsset
,
in
.
RightAsset
)
{
if
!
CheckExchangeAsset
(
in
.
LeftAsset
,
in
.
RightAsset
)
{
return
nil
,
et
.
ErrAsset
return
nil
,
et
.
ErrAsset
}
}
if
!
CheckPrice
(
in
.
Price
)
{
return
nil
,
et
.
ErrAssetPrice
}
if
!
CheckOp
(
in
.
Op
)
{
if
!
CheckOp
(
in
.
Op
)
{
return
nil
,
et
.
ErrAssetOp
return
nil
,
et
.
ErrAssetOp
...
...
plugin/dapp/exchange/proto/exchange.proto
View file @
5d8922a2
...
@@ -7,7 +7,7 @@ message Exchange {
...
@@ -7,7 +7,7 @@ message Exchange {
message
ExchangeAction
{
message
ExchangeAction
{
oneof
value
{
oneof
value
{
LimitOrder
limitOrder
=
1
;
LimitOrder
limitOrder
=
1
;
//
MarketOrder marketOrder = 2;
MarketOrder
marketOrder
=
2
;
RevokeOrder
revokeOrder
=
3
;
RevokeOrder
revokeOrder
=
3
;
}
}
int32
ty
=
6
;
int32
ty
=
6
;
...
...
plugin/dapp/exchange/types/exchange.pb.go
View file @
5d8922a2
...
@@ -59,6 +59,7 @@ func (*Exchange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0}
...
@@ -59,6 +59,7 @@ func (*Exchange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0}
type
ExchangeAction
struct
{
type
ExchangeAction
struct
{
// Types that are valid to be assigned to Value:
// Types that are valid to be assigned to Value:
// *ExchangeAction_LimitOrder
// *ExchangeAction_LimitOrder
// *ExchangeAction_MarketOrder
// *ExchangeAction_RevokeOrder
// *ExchangeAction_RevokeOrder
Value
isExchangeAction_Value
`protobuf_oneof:"value"`
Value
isExchangeAction_Value
`protobuf_oneof:"value"`
Ty
int32
`protobuf:"varint,6,opt,name=ty" json:"ty,omitempty"`
Ty
int32
`protobuf:"varint,6,opt,name=ty" json:"ty,omitempty"`
...
@@ -76,11 +77,15 @@ type isExchangeAction_Value interface {
...
@@ -76,11 +77,15 @@ type isExchangeAction_Value interface {
type
ExchangeAction_LimitOrder
struct
{
type
ExchangeAction_LimitOrder
struct
{
LimitOrder
*
LimitOrder
`protobuf:"bytes,1,opt,name=limitOrder,oneof"`
LimitOrder
*
LimitOrder
`protobuf:"bytes,1,opt,name=limitOrder,oneof"`
}
}
type
ExchangeAction_MarketOrder
struct
{
MarketOrder
*
MarketOrder
`protobuf:"bytes,2,opt,name=marketOrder,oneof"`
}
type
ExchangeAction_RevokeOrder
struct
{
type
ExchangeAction_RevokeOrder
struct
{
RevokeOrder
*
RevokeOrder
`protobuf:"bytes,3,opt,name=revokeOrder,oneof"`
RevokeOrder
*
RevokeOrder
`protobuf:"bytes,3,opt,name=revokeOrder,oneof"`
}
}
func
(
*
ExchangeAction_LimitOrder
)
isExchangeAction_Value
()
{}
func
(
*
ExchangeAction_LimitOrder
)
isExchangeAction_Value
()
{}
func
(
*
ExchangeAction_MarketOrder
)
isExchangeAction_Value
()
{}
func
(
*
ExchangeAction_RevokeOrder
)
isExchangeAction_Value
()
{}
func
(
*
ExchangeAction_RevokeOrder
)
isExchangeAction_Value
()
{}
func
(
m
*
ExchangeAction
)
GetValue
()
isExchangeAction_Value
{
func
(
m
*
ExchangeAction
)
GetValue
()
isExchangeAction_Value
{
...
@@ -97,6 +102,13 @@ func (m *ExchangeAction) GetLimitOrder() *LimitOrder {
...
@@ -97,6 +102,13 @@ func (m *ExchangeAction) GetLimitOrder() *LimitOrder {
return
nil
return
nil
}
}
func
(
m
*
ExchangeAction
)
GetMarketOrder
()
*
MarketOrder
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
ExchangeAction_MarketOrder
);
ok
{
return
x
.
MarketOrder
}
return
nil
}
func
(
m
*
ExchangeAction
)
GetRevokeOrder
()
*
RevokeOrder
{
func
(
m
*
ExchangeAction
)
GetRevokeOrder
()
*
RevokeOrder
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
ExchangeAction_RevokeOrder
);
ok
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
ExchangeAction_RevokeOrder
);
ok
{
return
x
.
RevokeOrder
return
x
.
RevokeOrder
...
@@ -115,6 +127,7 @@ func (m *ExchangeAction) GetTy() int32 {
...
@@ -115,6 +127,7 @@ func (m *ExchangeAction) GetTy() int32 {
func
(
*
ExchangeAction
)
XXX_OneofFuncs
()
(
func
(
msg
proto
.
Message
,
b
*
proto
.
Buffer
)
error
,
func
(
msg
proto
.
Message
,
tag
,
wire
int
,
b
*
proto
.
Buffer
)
(
bool
,
error
),
func
(
msg
proto
.
Message
)
(
n
int
),
[]
interface
{})
{
func
(
*
ExchangeAction
)
XXX_OneofFuncs
()
(
func
(
msg
proto
.
Message
,
b
*
proto
.
Buffer
)
error
,
func
(
msg
proto
.
Message
,
tag
,
wire
int
,
b
*
proto
.
Buffer
)
(
bool
,
error
),
func
(
msg
proto
.
Message
)
(
n
int
),
[]
interface
{})
{
return
_ExchangeAction_OneofMarshaler
,
_ExchangeAction_OneofUnmarshaler
,
_ExchangeAction_OneofSizer
,
[]
interface
{}{
return
_ExchangeAction_OneofMarshaler
,
_ExchangeAction_OneofUnmarshaler
,
_ExchangeAction_OneofSizer
,
[]
interface
{}{
(
*
ExchangeAction_LimitOrder
)(
nil
),
(
*
ExchangeAction_LimitOrder
)(
nil
),
(
*
ExchangeAction_MarketOrder
)(
nil
),
(
*
ExchangeAction_RevokeOrder
)(
nil
),
(
*
ExchangeAction_RevokeOrder
)(
nil
),
}
}
}
}
...
@@ -128,6 +141,11 @@ func _ExchangeAction_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
...
@@ -128,6 +141,11 @@ func _ExchangeAction_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
if
err
:=
b
.
EncodeMessage
(
x
.
LimitOrder
);
err
!=
nil
{
if
err
:=
b
.
EncodeMessage
(
x
.
LimitOrder
);
err
!=
nil
{
return
err
return
err
}
}
case
*
ExchangeAction_MarketOrder
:
b
.
EncodeVarint
(
2
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
MarketOrder
);
err
!=
nil
{
return
err
}
case
*
ExchangeAction_RevokeOrder
:
case
*
ExchangeAction_RevokeOrder
:
b
.
EncodeVarint
(
3
<<
3
|
proto
.
WireBytes
)
b
.
EncodeVarint
(
3
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
RevokeOrder
);
err
!=
nil
{
if
err
:=
b
.
EncodeMessage
(
x
.
RevokeOrder
);
err
!=
nil
{
...
@@ -151,6 +169,14 @@ func _ExchangeAction_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto
...
@@ -151,6 +169,14 @@ func _ExchangeAction_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto
err
:=
b
.
DecodeMessage
(
msg
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
ExchangeAction_LimitOrder
{
msg
}
m
.
Value
=
&
ExchangeAction_LimitOrder
{
msg
}
return
true
,
err
return
true
,
err
case
2
:
// value.marketOrder
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
MarketOrder
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
ExchangeAction_MarketOrder
{
msg
}
return
true
,
err
case
3
:
// value.revokeOrder
case
3
:
// value.revokeOrder
if
wire
!=
proto
.
WireBytes
{
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
return
true
,
proto
.
ErrInternalBadWireType
...
@@ -173,6 +199,11 @@ func _ExchangeAction_OneofSizer(msg proto.Message) (n int) {
...
@@ -173,6 +199,11 @@ func _ExchangeAction_OneofSizer(msg proto.Message) (n int) {
n
+=
proto
.
SizeVarint
(
1
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
1
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
n
+=
s
case
*
ExchangeAction_MarketOrder
:
s
:=
proto
.
Size
(
x
.
MarketOrder
)
n
+=
proto
.
SizeVarint
(
2
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
*
ExchangeAction_RevokeOrder
:
case
*
ExchangeAction_RevokeOrder
:
s
:=
proto
.
Size
(
x
.
RevokeOrder
)
s
:=
proto
.
Size
(
x
.
RevokeOrder
)
n
+=
proto
.
SizeVarint
(
3
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
3
<<
3
|
proto
.
WireBytes
)
...
@@ -931,46 +962,47 @@ var _Exchange_serviceDesc = grpc.ServiceDesc{
...
@@ -931,46 +962,47 @@ var _Exchange_serviceDesc = grpc.ServiceDesc{
func
init
()
{
proto
.
RegisterFile
(
"exchange.proto"
,
fileDescriptor0
)
}
func
init
()
{
proto
.
RegisterFile
(
"exchange.proto"
,
fileDescriptor0
)
}
var
fileDescriptor0
=
[]
byte
{
var
fileDescriptor0
=
[]
byte
{
// 649 bytes of a gzipped FileDescriptorProto
// 658 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xb4
,
0x55
,
0xdd
,
0x6a
,
0xd4
,
0x40
,
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xb4
,
0x55
,
0xed
,
0x6a
,
0xd4
,
0x4c
,
0x14
,
0xee
,
0xe4
,
0xa7
,
0xdb
,
0x9c
,
0x95
,
0xad
,
0x0e
,
0xa2
,
0x41
,
0x44
,
0x96
,
0x5c
,
0xd4
,
0x22
,
0x14
,
0x6e
,
0xbe
,
0xba
,
0xcd
,
0xd9
,
0x97
,
0xed
,
0xeb
,
0x20
,
0x1a
,
0x44
,
0x64
,
0xc9
,
0x8f
,
0x5a
,
0xba
,
0x42
,
0x0b
,
0xfe
,
0x5c
,
0x56
,
0x2b
,
0xb4
,
0x50
,
0xa9
,
0x0e
,
0xbe
,
0x40
,
0x9a
,
0x1c
,
0xbb
,
0x44
,
0x57
,
0x68
,
0xc1
,
0x8f
,
0x9f
,
0xd5
,
0x0a
,
0x2d
,
0x54
,
0xaa
,
0x83
,
0x37
,
0x90
,
0x26
,
0xc7
,
0xa1
,
0xd9
,
0x4d
,
0x48
,
0x26
,
0xa5
,
0x8b
,
0xaf
,
0x20
,
0x78
,
0xe7
,
0x13
,
0x28
,
0xf8
,
0x12
,
0xe2
,
0x6e
,
0x68
,
0x76
,
0x13
,
0x92
,
0xd9
,
0xd2
,
0xc5
,
0x5b
,
0x10
,
0xbc
,
0x09
,
0x05
,
0x6f
,
0x42
,
0xbc
,
0xab
,
0xc9
,
0x9c
,
0x4c
,
0x32
,
0xd3
,
0x1f
,
0xa9
,
0xa0
,
0x7b
,
0x97
,
0x6f
,
0xce
,
0x4f
,
0xbe
,
0x73
,
0x03
,
0xaf
,
0x49
,
0xe6
,
0xcc
,
0x24
,
0x33
,
0xdb
,
0xae
,
0x54
,
0xd4
,
0xfd
,
0x97
,
0x67
,
0xce
,
0x47
,
0xce
,
0x77
,
0x66
,
0x60
,
0x84
,
0x67
,
0xc9
,
0x34
,
0x9e
,
0x1f
,
0xe3
,
0xa4
,
0xac
,
0x0a
,
0x59
,
0x70
,
0x9e
,
0x73
,
0xce
,
0x73
,
0x66
,
0x60
,
0x80
,
0x17
,
0xe9
,
0x38
,
0x99
,
0x9e
,
0xe2
,
0xa8
,
0xaa
,
0x4b
,
0x5f
,
0x2e
,
0x4a
,
0xac
,
0x23
,
0x80
,
0xb5
,
0x37
,
0xda
,
0x10
,
0x7d
,
0x65
,
0x30
,
0xea
,
0xc0
,
0x4e
,
0x51
,
0xb2
,
0x40
,
0xcc
,
0x2b
,
0x6c
,
0x62
,
0x80
,
0x8d
,
0x57
,
0xda
,
0x10
,
0xff
,
0x70
,
0x60
,
0xd0
,
0x22
,
0xb3
,
0x62
,
0xce
,
0xb7
,
0x01
,
0xf2
,
0x6c
,
0x96
,
0xc9
,
0xc3
,
0x2a
,
0xc5
,
0x2a
,
0x64
,
0x63
,
0x82
,
0xbd
,
0x54
,
0xe4
,
0xe5
,
0x94
,
0xed
,
0x02
,
0x14
,
0xf9
,
0x24
,
0x17
,
0xc7
,
0x75
,
0x86
,
0x75
,
0xb6
,
0x39
,
0xdc
,
0xba
,
0x35
,
0xa1
,
0xd0
,
0xc9
,
0x41
,
0x6f
,
0xd8
,
0x5b
,
0x11
,
0x96
,
0x1b
,
0x7f
,
0xe4
,
0x0c
,
0x9d
,
0xed
,
0xfe
,
0xce
,
0x8d
,
0x11
,
0x85
,
0x8e
,
0x8e
,
0x3a
,
0xc3
,
0xc1
,
0x1a
,
0xb7
,
0x06
,
0xc3
,
0x0a
,
0x4f
,
0x8b
,
0x13
,
0x6c
,
0xa3
,
0x5c
,
0x8a
,
0xe2
,
0x3a
,
0x4a
,
0x18
,
0xcb
,
0xde
,
0xdc
,
0xd8
,
0x13
,
0xe8
,
0x4f
,
0x92
,
0xfa
,
0x0c
,
0x75
,
0x94
,
0x4b
,
0x51
,
0x4c
,
0x47
,
0xbd
,
0x36
,
0x8a
,
0xb0
,
0x1d
,
0xf9
,
0x08
,
0x1c
,
0xb9
,
0x08
,
0x57
,
0xc7
,
0x6c
,
0xd3
,
0x17
,
0x8e
,
0x5c
,
0xbc
,
0x96
,
0x83
,
0x35
,
0x6e
,
0x3b
,
0xca
,
0xb8
,
0x1a
,
0xcf
,
0xcb
,
0x33
,
0x54
,
0x71
,
0xde
,
0x42
,
0x1c
,
0x1a
,
0x80
,
0x7f
,
0x1a
,
0xe7
,
0x0d
,
0x46
,
0xdf
,
0x18
,
0x80
,
0xf9
,
0x1b
,
0x7f
,
0x04
,
0x41
,
0x8e
,
0x37
,
0x16
,
0x19
,
0x67
,
0x39
,
0xb2
,
0x01
,
0xb8
,
0x62
,
0x1e
,
0xad
,
0x0f
,
0x9d
,
0xed
,
0x80
,
0xbb
,
0x1f
,
0xe5
,
0x4e
,
0x5d
,
0xa3
,
0xd4
,
0x9c
,
0x6e
,
0xe8
,
0xec
,
0x74
,
0x26
,
0x8c
,
0x99
,
0x3f
,
0x06
,
0x62
,
0xfe
,
0xa2
,
0x07
,
0xc1
,
0x79
,
0x52
,
0xcc
,
0x30
,
0xfe
,
0xec
,
0x00
,
0x18
,
0x96
,
0xec
,
0x01
,
0xa8
,
0xb2
,
0xe3
,
0xa9
,
0x76
,
0x76
,
0xae
,
0x70
,
0xb6
,
0xec
,
0xfc
,
0x36
,
0xf8
,
0x65
,
0x95
,
0x25
,
0x84
,
0x05
,
0xbe
,
0x17
,
0x7b
,
0x4d
,
0x83
,
0x42
,
0xd7
,
0xf2
,
0x9f
,
0xce
,
0x4e
,
0x67
,
0xdc
,
0x98
,
0x48
,
0x9c
,
0x1d
,
0xd1
,
0x02
,
0x7e
,
0x07
,
0x56
,
0xe3
,
0x59
,
0xd1
,
0xcc
,
0x65
,
0xe8
,
0x8d
,
0xd9
,
0xd9
,
0x43
,
0x80
,
0x3a
,
0x3f
,
0x1d
,
0x6b
,
0x67
,
0x77
,
0x89
,
0xb3
,
0x65
,
0x67
,
0x37
,
0x21
,
0xa8
,
0xa6
,
0x2b
,
0x34
,
0x52
,
0x7c
,
0x8b
,
0x32
,
0xf4
,
0x5b
,
0xbe
,
0x45
,
0x19
,
0x7d
,
0x61
,
0x30
,
0x7c
,
0xea
,
0x3c
,
0x45
,
0xe2
,
0xec
,
0x72
,
0x05
,
0xd8
,
0x2d
,
0x58
,
0x4f
,
0x26
,
0xe5
,
0x6c
,
0x2a
,
0x22
,
0x1b
,
0x57
,
0x27
,
0xb8
,
0x74
,
0x9e
,
0x86
,
0x91
,
0x7b
,
0x05
,
0x23
,
0xaf
,
0x67
,
0xf4
,
0x10
,
0x86
,
0x7f
,
0xe8
,
0x6c
,
0x7b
,
0x5c
,
0x23
,
0xc9
,
0xb7
,
0xac
,
0xa2
,
0x40
,
0xf1
,
0x2d
,
0xab
,
0xf8
,
0x93
,
0x56
,
0xbf
,
0x79
,
0x08
,
0x83
,
0x42
,
0x7d
,
0xec
,
0xef
,
0x12
,
0x9d
,
0x40
,
0x74
,
0x30
,
0x7a
,
0x0e
,
0x03
,
0x7d
,
0xab
,
0x2d
,
0x2b
,
0xe4
,
0x69
,
0x18
,
0x79
,
0x4b
,
0x18
,
0xf9
,
0x1d
,
0xa3
,
0xfb
,
0xd0
,
0x7e
,
0x9f
,
0x19
,
0xcf
,
0x30
,
0xd1
,
0xc3
,
0x0e
,
0x84
,
0x46
,
0xea
,
0xbc
,
0x5e
,
0xcc
,
0x8e
,
0x8a
,
0xb7
,
0xfa
,
0xcd
,
0x22
,
0xe8
,
0x95
,
0xf2
,
0xe3
,
0x70
,
0x9f
,
0xe8
,
0x84
,
0xbc
,
0x85
,
0xf1
,
0x53
,
0x9c
,
0xb8
,
0x05
,
0x42
,
0xa3
,
0xe8
,
0x97
,
0x03
,
0xfe
,
0x35
,
0xc9
,
0x2f
,
0x88
,
0xc8
,
0xf9
,
0x6b
,
0x08
,
0xba
,
0xcc
,
0x78
,
0x81
,
0xa9
,
0x16
,
0x49
,
0xc8
,
0x35
,
0x92
,
0xe7
,
0xcd
,
0x7c
,
0x72
,
0x52
,
0x11
,
0xcd
,
0x4c
,
0x2f
,
0x2f
,
0x88
,
0xc8
,
0xea
,
0xb2
,
0x12
,
0x91
,
0xe5
,
0xa8
,
0x45
,
0xe4
,
0x75
,
0x16
,
0xc4
,
0x2d
,
0xe4
,
0x1a
,
0xc5
,
0xdf
,
0x5d
,
0x08
,
0xae
,
0x49
,
0x7e
,
0x49
,
0x7c
,
0xee
,
0x1f
,
0x22
,
0xe2
,
0xf7
,
0x60
,
0x4d
,
0x95
,
0xd0
,
0x48
,
0x4c
,
0x69
,
0x54
,
0xae
,
0xe8
,
0xb1
,
0xa2
,
0x7c
,
0x89
,
0xcf
,
0xfb
,
0x5d
,
0xf1
,
0x29
,
0x11
,
0xf9
,
0xad
,
0x88
,
0xd8
,
0x1d
,
0xd8
,
0x90
,
0x25
,
0xcc
,
0x14
,
0xe7
,
0xf1
,
0x3c
,
0x41
,
0x52
,
0x9d
,
0x2b
,
0x3a
,
0x48
,
0xe5
,
0xca
,
0x58
,
0x36
,
0x75
,
0x38
,
0x04
,
0x66
,
0x34
,
0x2a
,
0x8f
,
0x77
,
0x58
,
0x52
,
0x3e
,
0x49
,
0x8a
,
0x64
,
0x9a
,
0x22
,
0xa9
,
0xce
,
0xa0
,
0x4c
,
0x1a
,
0x71
,
0x0e
,
0x5e
,
0x9c
,
0xa6
,
0x55
,
0xb8
,
0x46
,
0x15
,
0xd2
,
0x37
,
0x7f
,
0x00
,
0xe3
,
0x2d
,
0xa4
,
0x72
,
0x45
,
0x22
,
0x66
,
0x4d
,
0xd4
,
0xa3
,
0x4c
,
0x1a
,
0x31
,
0x06
,
0x7e
,
0x92
,
0xd0
,
0x94
,
0x69
,
0x2c
,
0xf1
,
0x43
,
0x36
,
0xc3
,
0x30
,
0xa0
,
0x44
,
0xd6
,
0x89
,
0x12
,
0x55
,
0x36
,
0x65
,
0x75
,
0xb4
,
0x41
,
0x15
,
0xd2
,
0x37
,
0xbb
,
0x07
,
0x30
,
0xab
,
0xb2
,
0x44
,
0xe0
,
0xbb
,
0x7c
,
0x4f
,
0xf1
,
0x2c
,
0x04
,
0x32
,
0xb5
,
0xc0
,
0x88
,
0xfb
,
0x05
,
0x00
,
0x31
,
0x7f
,
0x47
,
0x5a
,
0xeb
,
0x82
,
0x51
,
0x48
,
0x89
,
0xac
,
0x13
,
0x29
,
0xaa
,
0x7c
,
0x9a
,
0xe1
,
0x45
,
0x04
,
0x64
,
0x52
,
0xc0
,
0x15
,
0xc8
,
0x6c
,
0x05
,
0xf6
,
0x29
,
0x1c
,
0x2b
,
0x45
,
0xf4
,
0x14
,
0x06
,
0x87
,
0xba
,
0xc5
,
0x23
,
0x88
,
0xfb
,
0x19
,
0x00
,
0x31
,
0x7f
,
0x43
,
0x5a
,
0xeb
,
0x14
,
0xe8
,
0xd8
,
0x0a
,
0xec
,
0x52
,
0xb8
,
0x70
,
0xfa
,
0xbe
,
0x3b
,
0xfb
,
0xbb
,
0x7f
,
0x08
,
0xf8
,
0xc1
,
0xe0
,
0xe6
,
0xfb
,
0x06
,
0xab
,
0x45
,
0x56
,
0x8a
,
0xf8
,
0x31
,
0xf4
,
0x8e
,
0x75
,
0x8b
,
0x07
,
0xe0
,
0x76
,
0x7d
,
0x77
,
0x0f
,
0xf7
,
0x7f
,
0xdb
,
0xbf
,
0x5d
,
0x2c
,
0xe5
,
0x74
,
0x89
,
0x2a
,
0x6d
,
0xd5
,
0xe8
,
0x76
,
0x6a
,
0x34
,
0xb5
,
0x79
,
0x11
,
0xf0
,
0xd5
,
0x81
,
0xff
,
0xdf
,
0xce
,
0xb0
,
0x9e
,
0xab
,
0xfe
,
0xed
,
0x63
,
0x25
,
0xc6
,
0x2b
,
0x17
,
0x6a
,
0x4b
,
0x48
,
0xca
,
0xed
,
0x22
,
0xb5
,
0x20
,
0xfa
,
0xde
,
0xef
,
0xd2
,
0xb2
,
0x59
,
0xfe
,
0x54
,
0xa9
,
0x52
,
0xa3
,
0xd7
,
0xaa
,
0xd1
,
0xd4
,
0xe6
,
0x5f
,
0xaa
,
0x2d
,
0x25
,
0x29
,
0xab
,
0x45
,
0xdb
,
0xce
,
0xbf
,
0x84
,
0x75
,
0x8b
,
0xe6
,
0x41
,
0x56
,
0x4b
,
0xbe
,
0x01
,
0x5e
,
0x9e
,
0xd5
,
0x8a
,
0x52
,
0x20
,
0xfe
,
0xd2
,
0xed
,
0xd2
,
0xaa
,
0x59
,
0xfe
,
0xdd
,
0xce
,
0x3f
,
0x87
,
0x4d
,
0x8b
,
0xe6
,
0xa5
,
0x7b
,
0x49
,
0xb2
,
0xe4
,
0x25
,
0xc8
,
0x1e
,
0xfd
,
0x64
,
0x70
,
0x97
,
0xa6
,
0xf1
,
0xba
,
0x98
,
0x51
,
0xde
,
0x08
,
0xb6
,
0x05
,
0x7e
,
0x91
,
0x37
,
0x92
,
0xa5
,
0x77
,
0x45
,
0xb2
,
0xe4
,
0xc5
,
0xc9
,
0x95
,
0x39
,
0x4a
,
0x4c
,
0x69
,
0x9a
,
0x94
,
0x63
,
0xa9
,
0xe5
,
0xb6
,
0xca
,
0x70
,
0x2d
,
0x65
,
0x98
,
0x1e
,
0x7f
,
0x73
,
0xe0
,
0x36
,
0x4d
,
0xe3
,
0x65
,
0x39
,
0xa9
,
0x0a
,
0x14
,
0x98
,
0xd1
,
0x34
,
0x29
,
0x21
,
0x78
,
0xd6
,
0x10
,
0xf8
,
0x7d
,
0x08
,
0xd2
,
0xac
,
0x42
,
0x7a
,
0x0a
,
0x74
,
0xcd
,
0xe6
,
0x20
,
0xc7
,
0x4a
,
0xcb
,
0x55
,
0xca
,
0xf0
,
0x2c
,
0x65
,
0x98
,
0x21
,
0xf8
,
0xd6
,
0x10
,
0xd8
,
0x5d
,
0x08
,
0xda
,
0x00
,
0x20
,
0xfa
,
0xd7
,
0xdd
,
0x2d
,
0x9f
,
0x19
,
0x8c
,
0x8c
,
0x23
,
0x95
,
0x67
,
0xd6
,
0x8b
,
0xb3
,
0xbc
,
0x46
,
0x7a
,
0x42
,
0x74
,
0xcd
,
0xe6
,
0x20
,
0xde
,
0x02
,
0x20
,
0xfa
,
0xd7
,
0xdd
,
0x2d
,
0x9d
,
0x5b
,
0xaf
,
0x10
,
0x06
,
0x6a
,
0xa5
,
0xb0
,
0xae
,
0xf5
,
0x35
,
0xd3
,
0xc1
,
0xff
,
0x48
,
0xfb
,
0x1f
,
0x1d
,
0x18
,
0x18
,
0x47
,
0x2a
,
0xcf
,
0xac
,
0x97
,
0xb3
,
0xb0
,
0x5e
,
0x11
,
0xf4
,
0xe4
,
0x4a
,
0x09
,
0x04
,
0x86
,
0xc8
,
0xf8
,
0xdc
,
0xac
,
0xba
,
0xae
,
0x91
,
0x5d
,
0x4f
,
0xe9
,
0x13
,
0xac
,
0x0b
,
0x61
,
0xd3
,
0xe8
,
0x6b
,
0xa6
,
0x85
,
0xff
,
0x90
,
0xf6
,
0x23
,
0x08
,
0x0d
,
0x91
,
0xe1
,
0xc2
,
0xac
,
0x4c
,
0x30
,
0x2b
,
0x65
,
0xf7
,
0x34
,
0xf2
,
0x08
,
0xfc
,
0xc2
,
0x7a
,
0x0f
,
0xcf
,
0x47
,
0xb5
,
0x26
,
0xda
,
0xae
,
0x91
,
0x5d
,
0x4f
,
0xe9
,
0x03
,
0x6c
,
0x72
,
0x4c
,
0x31
,
0xaf
,
0x44
,
0xfb
,
0xa4
,
0xb2
,
0x3e
,
0x51
,
0xd7
,
0x97
,
0x4c
,
0xa6
,
0x74
,
0xa8
,
0xaa
,
0xb9
,
0x9c
,
0xdf
,
0x76
,
0xb8
,
0xba
,
0xbe
,
0x18
,
0x82
,
0xd2
,
0x7a
,
0x47
,
0x17
,
0xa3
,
0x94
,
0x89
,
0x8d
,
0xe4
,
0xf5
,
0x25
,
0xd2
,
0x31
,
0x1d
,
0x2d
,
0x50
,
0x97
,
0x57
,
0xfb
,
0xd7
,
0xa3
,
0x55
,
0x7a
,
0xb7
,
0xb7
,
0x7f
,
0x07
,
0x00
,
0x00
,
0xff
,
0xca
,
0x6a
,
0xae
,
0xe6
,
0xb7
,
0x1d
,
0x96
,
0xd7
,
0xb7
,
0x03
,
0xf2
,
0xf2
,
0x52
,
0x7f
,
0x3d
,
0x59
,
0xff
,
0xe3
,
0xe1
,
0xf2
,
0x06
,
0xc9
,
0x07
,
0x00
,
0x00
,
0xa7
,
0xf7
,
0x7e
,
0xf7
,
0x67
,
0x00
,
0x00
,
0x00
,
0xff
,
0xff
,
0xb5
,
0x7b
,
0x52
,
0x3b
,
0x01
,
0x08
,
0x00
,
0x00
,
}
}
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