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
ef3012f1
Commit
ef3012f1
authored
Dec 18, 2019
by
harrylee
Committed by
vipwzw
Dec 26, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ajust sotage struct
parent
ca3650a2
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
779 additions
and
462 deletions
+779
-462
exchange_test.go
plugin/dapp/exchange/executor/exchange_test.go
+131
-32
exchangedb.go
plugin/dapp/exchange/executor/exchangedb.go
+125
-123
exec_local.go
plugin/dapp/exchange/executor/exec_local.go
+187
-73
kv.go
plugin/dapp/exchange/executor/kv.go
+0
-75
query.go
plugin/dapp/exchange/executor/query.go
+5
-5
tables.go
plugin/dapp/exchange/executor/tables.go
+224
-0
exchange.proto
plugin/dapp/exchange/proto/exchange.proto
+9
-17
exchange.go
plugin/dapp/exchange/types/exchange.go
+4
-1
exchange.pb.go
plugin/dapp/exchange/types/exchange.pb.go
+94
-136
No files found.
plugin/dapp/exchange/executor/exchange_test.go
View file @
ef3012f1
...
...
@@ -11,7 +11,6 @@ import (
"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"
...
...
@@ -62,9 +61,11 @@ func TestExchange(t *testing.T) {
Frozen
:
0
,
Addr
:
string
(
Nodes
[
3
]),
}
dir
,
ldb
,
kvdb
:=
util
.
CreateTestDB
()
defer
util
.
CloseTestDB
(
dir
,
ldb
)
execAddr
:=
address
.
ExecAddress
(
et
.
ExchangeX
)
stateDB
,
_
:=
dbm
.
NewGoMemDB
(
"1"
,
"2"
,
5000
)
_
,
_
,
kvdb
:=
util
.
CreateTestDB
()
//
stateDB, _ := dbm.NewGoMemDB("1", "2", 5000)
_
,
stateDB
,
kvdb
:=
util
.
CreateTestDB
()
accA
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accA
.
SaveExecAccount
(
execAddr
,
&
accountA
)
...
...
@@ -104,6 +105,7 @@ func TestExchange(t *testing.T) {
tx
,
err
=
types
.
FormatTx
(
cfg
,
et
.
ExchangeX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
t
.
Log
(
tx
)
assert
.
Nil
(
t
,
err
)
exec
:=
newExchange
()
e
:=
exec
.
(
*
exchange
)
...
...
@@ -134,9 +136,19 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
orderID1
:=
common
.
ToHex
(
tx
.
Hash
())
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
assert
.
Equal
(
t
,
types
.
ExecOk
,
int
(
receipt
.
Ty
))
//根据地址状态查看订单,最新得订单号永远是在list[0],第一位
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
)
orderID1
:=
reply2
.
List
[
0
]
.
OrderID
//根据订单号,查询订单详情
msg
,
err
:
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID1
}))
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID1
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
...
...
@@ -158,16 +170,6 @@ func TestExchange(t *testing.T) {
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
})
...
...
@@ -197,7 +199,17 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
orderID2
:=
common
.
ToHex
(
tx
.
Hash
())
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
assert
.
Equal
(
t
,
types
.
ExecOk
,
int
(
receipt
.
Ty
))
//根据地址状态查看订单
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Completed
,
Address
:
string
(
Nodes
[
1
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
orderList
:=
msg
.
(
*
et
.
OrderList
)
orderID2
:=
orderList
.
List
[
0
]
.
OrderID
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID1
}))
if
err
!=
nil
{
...
...
@@ -266,6 +278,8 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID1
}))
if
err
!=
nil
{
...
...
@@ -314,7 +328,17 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
orderID3
:=
common
.
ToHex
(
tx
.
Hash
())
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
assert
.
Equal
(
t
,
types
.
ExecOk
,
int
(
receipt
.
Ty
))
//根据地址状态查看订单
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
)
orderList
=
msg
.
(
*
et
.
OrderList
)
orderID3
:=
orderList
.
List
[
0
]
.
OrderID
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID3
}))
if
err
!=
nil
{
t
.
Error
(
err
)
...
...
@@ -352,7 +376,16 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
orderID4
:=
common
.
ToHex
(
tx
.
Hash
())
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
//根据地址状态查看订单
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
)
orderList
=
msg
.
(
*
et
.
OrderList
)
orderID4
:=
orderList
.
List
[
0
]
.
OrderID
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID4
}))
if
err
!=
nil
{
...
...
@@ -412,8 +445,16 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
orderID5
:=
common
.
ToHex
(
tx
.
Hash
())
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Completed
,
Address
:
string
(
Nodes
[
1
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
orderList
=
msg
.
(
*
et
.
OrderList
)
orderID5
:=
orderList
.
List
[
0
]
.
OrderID
//
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID5
}))
if
err
!=
nil
{
...
...
@@ -426,13 +467,11 @@ func TestExchange(t *testing.T) {
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
)
assert
.
Equal
(
t
,
types
.
ErrNotFound
,
err
)
}
reply1
=
msg
.
(
*
et
.
MarketDepthList
)
t
.
Log
(
reply1
.
List
)
//根据状态和地址查询
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Completed
,
Address
:
string
(
Nodes
[
0
])}))
//
//
根据状态和地址查询
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Completed
,
Address
:
string
(
Nodes
[
1
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
...
...
@@ -476,7 +515,16 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
orderID6
:=
common
.
ToHex
(
tx
.
Hash
())
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
//根据地址状态查看订单
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Ordered
,
Address
:
string
(
Nodes
[
3
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
orderList
=
msg
.
(
*
et
.
OrderList
)
orderID6
:=
orderList
.
List
[
0
]
.
OrderID
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID6
}))
if
err
!=
nil
{
...
...
@@ -513,9 +561,18 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
orderID7
:=
common
.
ToHex
(
tx
.
Hash
())
//根据订单号,查询订单详情
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
//根据地址状态查看订单
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Ordered
,
Address
:
string
(
Nodes
[
2
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
orderList
=
msg
.
(
*
et
.
OrderList
)
orderID7
:=
orderList
.
List
[
0
]
.
OrderID
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID6
}))
if
err
!=
nil
{
t
.
Error
(
err
)
...
...
@@ -535,7 +592,6 @@ func TestExchange(t *testing.T) {
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"
},
...
...
@@ -567,7 +623,16 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
orderID8
:=
common
.
ToHex
(
tx
.
Hash
())
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
//根据地址状态查看订单
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Ordered
,
Address
:
string
(
Nodes
[
2
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
orderList
=
msg
.
(
*
et
.
OrderList
)
orderID8
:=
orderList
.
List
[
0
]
.
OrderID
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
})
...
...
@@ -598,7 +663,16 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
orderID9
:=
common
.
ToHex
(
tx
.
Hash
())
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
//根据地址状态查看订单
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Ordered
,
Address
:
string
(
Nodes
[
2
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
orderList
=
msg
.
(
*
et
.
OrderList
)
orderID9
:=
orderList
.
List
[
0
]
.
OrderID
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
)
...
...
@@ -627,7 +701,16 @@ func TestExchange(t *testing.T) {
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
orderID10
:=
common
.
ToHex
(
tx
.
Hash
())
//save to database
util
.
SaveKVList
(
stateDB
,
set
.
KV
)
//根据地址状态查看订单
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrderList
,
types
.
Encode
(
&
et
.
QueryOrderList
{
Status
:
et
.
Ordered
,
Address
:
string
(
Nodes
[
3
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
orderList
=
msg
.
(
*
et
.
OrderList
)
orderID10
:=
orderList
.
List
[
0
]
.
OrderID
//根据订单号,查询订单详情
msg
,
err
=
exec
.
Query
(
et
.
FuncNameQueryOrder
,
types
.
Encode
(
&
et
.
QueryOrder
{
OrderID
:
orderID7
}))
if
err
!=
nil
{
...
...
@@ -703,3 +786,19 @@ func TestCheckPrice(t *testing.T) {
t
.
Log
(
CheckPrice
(
Truncate
(
float64
(
1e-8
))))
t
.
Log
(
CheckPrice
(
Truncate
(
float64
(
1e-9
))))
}
func
TestRawMeta
(
t
*
testing
.
T
)
{
CompletedOrderRow
:=
NewCompletedOrderRow
()
t
.
Log
(
CompletedOrderRow
.
Get
(
"index"
))
MarketDepthRow
:=
NewMarketDepthRow
()
t
.
Log
(
MarketDepthRow
.
Get
(
"price"
))
marketOrderRow
:=
NewOrderRow
()
t
.
Log
(
marketOrderRow
.
Get
(
"orderID"
))
UserOrderRow
:=
NewUserOrderRow
()
t
.
Log
(
UserOrderRow
.
Get
(
"index"
))
}
func
TestKV
(
t
*
testing
.
T
)
{
a
:=
&
types
.
KeyValue
{
Key
:
[]
byte
(
"1111111"
),
Value
:
nil
}
t
.
Log
(
a
.
Key
,
a
.
Value
)
}
plugin/dapp/exchange/executor/exchangedb.go
View file @
ef3012f1
...
...
@@ -6,12 +6,12 @@ import (
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/common"
//
"github.com/33cn/chain33/common"
dbm
"github.com/33cn/chain33/common/db"
.
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
et
"github.com/33cn/plugin/plugin/dapp/exchange/types"
"github.com/gogo/protobuf/proto"
)
// Action action struct
...
...
@@ -22,7 +22,7 @@ type Action struct {
blocktime
int64
height
int64
execaddr
string
localDB
dbm
.
Lister
localDB
dbm
.
KVDB
index
int
api
client
.
QueueProtocolAPI
}
...
...
@@ -170,7 +170,8 @@ func (a *Action) LimitOrder(payload *et.LimitOrder) (*types.Receipt, error) {
func
(
a
*
Action
)
RevokeOrder
(
payload
*
et
.
RevokeOrder
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
var
kvs
[]
*
types
.
KeyValue
order
,
err
:=
findOrderByOrderID
(
a
.
statedb
,
payload
.
GetOrderID
())
order
,
err
:=
findOrderByOrderID
(
a
.
statedb
,
a
.
localDB
,
payload
.
GetOrderID
())
elog
.
Info
(
"RevokeOrder===="
,
"order"
,
order
.
Balance
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -252,12 +253,12 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
func
(
a
*
Action
)
matchLimitOrder
(
payload
*
et
.
LimitOrder
,
leftAccountDB
,
rightAccountDB
*
account
.
DB
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
var
kvs
[]
*
types
.
KeyValue
var
index
int64
var
price
float64
var
orderKey
string
var
price
Key
string
var
count
int
or
:=
&
et
.
Order
{
OrderID
:
common
.
ToHex
(
a
.
txhash
),
OrderID
:
a
.
GetIndex
(
),
Value
:
&
et
.
Order_LimitOrder
{
LimitOrder
:
payload
},
Ty
:
et
.
TyLimitOrderAction
,
Executed
:
0
,
...
...
@@ -278,7 +279,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
if
count
>
et
.
MaxCount
{
break
}
marketDepthList
,
err
:=
QueryMarketDepth
(
a
.
localDB
,
payload
.
GetLeftAsset
(),
payload
.
GetRightAsset
(),
a
.
OpSwap
(
payload
.
Op
),
price
,
et
.
Count
)
marketDepthList
,
err
:=
QueryMarketDepth
(
a
.
localDB
,
payload
.
GetLeftAsset
(),
payload
.
GetRightAsset
(),
a
.
OpSwap
(
payload
.
Op
),
price
Key
,
et
.
Count
)
if
err
==
types
.
ErrNotFound
{
break
}
...
...
@@ -297,21 +298,15 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
}
//根据价格进行迭代
for
{
order
IDs
,
err
:=
findOrderIDListByPrice
(
a
.
localDB
,
payload
.
GetLeftAsset
(),
payload
.
GetRightAsset
(),
marketDepth
.
Price
,
a
.
OpSwap
(
payload
.
Op
),
et
.
ListASC
,
index
)
order
List
,
err
:=
findOrderIDListByPrice
(
a
.
localDB
,
payload
.
GetLeftAsset
(),
payload
.
GetRightAsset
(),
marketDepth
.
Price
,
a
.
OpSwap
(
payload
.
Op
),
et
.
ListASC
,
orderKey
)
if
err
==
types
.
ErrNotFound
{
continue
break
}
for
_
,
orderID
:=
range
orderIDs
{
matchorder
,
err
:=
findOrderByOrderID
(
a
.
statedb
,
orderID
.
ID
)
if
err
!=
nil
{
elog
.
Warn
(
"matchLimitOrder.findOrderByOrderID"
,
"order"
,
"err"
,
err
.
Error
())
continue
}
for
_
,
matchorder
:=
range
orderList
.
List
{
//同地址不能交易
if
matchorder
.
Addr
==
a
.
fromaddr
{
continue
}
//TODO 这里得逻辑是否需要调整?当匹配的单数过多,会导致receipt日志数量激增,理论上存在日志存储攻击,需要加下最大匹配深度,防止这种攻击发生
if
matchorder
.
GetBalance
()
>=
or
.
GetBalance
()
{
if
payload
.
Op
==
et
.
OpSell
{
...
...
@@ -461,18 +456,18 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
count
=
count
+
1
}
//查询数据不满足5条说明没有了,跳出循环
if
len
(
orderIDs
)
<
int
(
et
.
Count
)
{
if
orderList
.
PrimaryKey
==
""
{
break
}
index
=
orderIDs
[
len
(
orderIDs
)
-
1
]
.
Index
orderKey
=
orderList
.
PrimaryKey
}
}
//查询数据不满足5条说明没有了,跳出循环
if
len
(
marketDepthList
.
List
)
<
int
(
et
.
Count
)
{
if
marketDepthList
.
PrimaryKey
==
""
{
break
}
price
=
marketDepthList
.
List
[
len
(
marketDepthList
.
List
)
-
1
]
.
Price
price
Key
=
marketDepthList
.
PrimaryKey
}
//冻结剩余未成交的资金
...
...
@@ -501,55 +496,60 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
receipts
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kvs
,
Logs
:
logs
}
return
receipts
,
nil
}
func
findOrderByOrderID
(
statedb
dbm
.
KV
,
orderID
string
)
(
*
et
.
Order
,
error
)
{
data
,
err
:=
statedb
.
Get
(
calcOrderKey
(
orderID
))
if
err
!=
nil
{
elog
.
Error
(
"findOrderByOrderID.Get"
,
"orderID"
,
orderID
,
"err"
,
err
.
Error
())
return
nil
,
err
}
var
order
et
.
Order
err
=
types
.
Decode
(
data
,
&
order
)
//根据订单号查询,分为两步,优先去localdb中查询,如没有则再去状态数据库中查询
// 1.挂单中得订单信会根据orderID在localdb中存储
// 2.订单撤销,或者成交后,根据orderID在localdb中存储得数据会被删除,这时只能到状态数据库中查询
func
findOrderByOrderID
(
statedb
dbm
.
KV
,
localdb
dbm
.
KVDB
,
orderID
int64
)
(
*
et
.
Order
,
error
)
{
table
:=
NewMarketOrderTable
(
localdb
)
primaryKey
:=
[]
byte
(
fmt
.
Sprintf
(
"%022d"
,
orderID
))
row
,
err
:=
table
.
GetData
(
primaryKey
)
if
err
!=
nil
{
elog
.
Error
(
"findOrderByOrderID.Decode"
,
"orderID"
,
orderID
,
"err"
,
err
.
Error
())
return
nil
,
err
data
,
err
:=
statedb
.
Get
(
calcOrderKey
(
orderID
))
if
err
!=
nil
{
elog
.
Error
(
"findOrderByOrderID.Get"
,
"orderID"
,
orderID
,
"err"
,
err
.
Error
())
return
nil
,
err
}
var
order
et
.
Order
err
=
types
.
Decode
(
data
,
&
order
)
if
err
!=
nil
{
elog
.
Error
(
"findOrderByOrderID.Decode"
,
"orderID"
,
orderID
,
"err"
,
err
.
Error
())
return
nil
,
err
}
return
&
order
,
nil
}
return
&
order
,
nil
return
row
.
Data
.
(
*
et
.
Order
),
nil
}
func
findOrderIDListByPrice
(
localdb
dbm
.
Lister
,
left
,
right
*
et
.
Asset
,
price
float64
,
op
,
direction
int32
,
index
int64
)
([]
*
et
.
OrderID
,
error
)
{
prefix
:=
calcMarketDepthOrderPrefix
(
left
,
right
,
op
,
price
)
key
:=
calcMarketDepthOrderKey
(
left
,
right
,
op
,
price
,
index
)
var
values
[][]
byte
func
findOrderIDListByPrice
(
localdb
dbm
.
KVDB
,
left
,
right
*
et
.
Asset
,
price
float64
,
op
,
direction
int32
,
primaryKey
string
)
(
*
et
.
OrderList
,
error
)
{
table
:=
NewMarketOrderTable
(
localdb
)
query
:=
table
.
GetQuery
(
localdb
)
prefix
:=
[]
byte
(
fmt
.
Sprintf
(
"%s:%s:%d:%016d"
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
op
,
int64
(
Truncate
(
price
*
float64
(
1e8
)))))
var
rows
[]
*
Row
var
err
error
if
index
==
0
{
//第一次查询
values
,
err
=
localdb
.
List
(
prefix
,
nil
,
et
.
Count
,
direction
)
if
primaryKey
==
""
{
//第一次查询,默认展示最新得成交记录
rows
,
err
=
query
.
ListIndex
(
"market_order"
,
prefix
,
nil
,
et
.
Count
,
direction
)
}
else
{
values
,
err
=
localdb
.
List
(
prefix
,
key
,
et
.
Count
,
direction
)
rows
,
err
=
query
.
ListIndex
(
"market_order"
,
prefix
,
[]
byte
(
primaryKey
)
,
et
.
Count
,
direction
)
}
if
err
!=
nil
{
elog
.
Error
(
"findOrderIDListByPrice."
,
"left"
,
left
,
"right"
,
right
,
"price"
,
price
,
"err"
,
err
.
Error
())
return
nil
,
err
}
var
list
[]
*
et
.
OrderID
for
_
,
value
:=
range
values
{
var
orderID
et
.
OrderID
err
:=
types
.
Decode
(
value
,
&
orderID
)
if
err
!=
nil
{
elog
.
Warn
(
"findOrderIDListByPrice.Decode"
,
"orderID"
,
"err"
,
err
.
Error
())
continue
}
list
=
append
(
list
,
&
orderID
)
var
orderList
et
.
OrderList
for
_
,
row
:=
range
rows
{
order
:=
row
.
Data
.
(
*
et
.
Order
)
//替换已经成交得量
order
.
Executed
=
order
.
GetLimitOrder
()
.
Amount
-
order
.
Balance
orderList
.
List
=
append
(
orderList
.
List
,
order
)
}
return
list
,
nil
}
//localdb查询
func
findObject
(
localdb
dbm
.
KVDB
,
key
[]
byte
,
msg
proto
.
Message
)
error
{
value
,
err
:=
localdb
.
Get
(
key
)
if
err
!=
nil
{
elog
.
Warn
(
"findObject.Decode"
,
"key"
,
string
(
key
),
"err"
,
err
.
Error
())
return
err
//设置主键索引
if
len
(
rows
)
==
int
(
et
.
Count
)
{
orderList
.
PrimaryKey
=
string
(
rows
[
len
(
rows
)
-
1
]
.
Primary
)
}
return
types
.
Decode
(
value
,
msg
)
return
&
orderList
,
nil
}
//买单深度是按价格倒序,由高到低
...
...
@@ -560,112 +560,114 @@ func Direction(op int32) int32 {
return
et
.
ListASC
}
//这里price当作索引来用,首次查询不需要填值
func
QueryMarketDepth
(
localdb
dbm
.
Lister
,
left
,
right
*
et
.
Asset
,
op
int32
,
price
float64
,
count
int32
)
(
*
et
.
MarketDepthList
,
error
)
{
prefix
:=
calcMarketDepthPrefix
(
left
,
right
,
op
)
key
:=
calcMarketDepthKey
(
left
,
right
,
op
,
price
)
var
values
[][]
byte
//这里primaryKey当作主键索引来用,首次查询不需要填值
func
QueryMarketDepth
(
localdb
dbm
.
KVDB
,
left
,
right
*
et
.
Asset
,
op
int32
,
primaryKey
string
,
count
int32
)
(
*
et
.
MarketDepthList
,
error
)
{
table
:=
NewMarketDepthTable
(
localdb
)
query
:=
table
.
GetQuery
(
localdb
)
prefix
:=
[]
byte
(
fmt
.
Sprintf
(
"%s:%s:%d"
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
op
))
if
count
==
0
{
count
=
et
.
Count
}
var
rows
[]
*
Row
var
err
error
if
pri
ce
==
0
{
//第一次查询,方向卖单由低到高,买单由高到低
values
,
err
=
localdb
.
List
(
prefix
,
nil
,
count
,
Direction
(
op
))
if
pri
maryKey
==
""
{
//第一次查询,默认展示最新得成交记录
rows
,
err
=
query
.
ListIndex
(
"price"
,
prefix
,
nil
,
count
,
Direction
(
op
))
}
else
{
values
,
err
=
localdb
.
List
(
prefix
,
key
,
count
,
Direction
(
op
))
rows
,
err
=
query
.
ListIndex
(
"price"
,
prefix
,
[]
byte
(
primaryKey
)
,
count
,
Direction
(
op
))
}
if
err
!=
nil
{
elog
.
Error
(
"QueryMarketDepth."
,
"left"
,
left
,
"right"
,
right
,
"err"
,
err
.
Error
())
return
nil
,
err
}
var
list
et
.
MarketDepthList
for
_
,
value
:=
range
values
{
var
marketDept
et
.
MarketDepth
err
:=
types
.
Decode
(
value
,
&
marketDept
)
if
err
!=
nil
{
elog
.
Warn
(
"QueryMarketDepth.Decode"
,
"marketDept"
,
"err"
,
err
.
Error
())
continue
}
list
.
List
=
append
(
list
.
List
,
&
marketDept
)
for
_
,
row
:=
range
rows
{
list
.
List
=
append
(
list
.
List
,
row
.
Data
.
(
*
et
.
MarketDepth
))
}
//设置主键索引
if
len
(
rows
)
==
int
(
count
)
{
list
.
PrimaryKey
=
string
(
rows
[
len
(
rows
)
-
1
]
.
Primary
)
}
return
&
list
,
nil
}
//QueryCompletedOrderList
func
QueryCompletedOrderList
(
localdb
dbm
.
Lister
,
statedb
dbm
.
KV
,
left
,
right
*
et
.
Asset
,
index
int64
,
count
,
direction
int32
)
(
types
.
Message
,
error
)
{
prefix
:=
calcCompletedOrderPrefix
(
left
,
right
)
key
:=
calcCompletedOrderKey
(
left
,
right
,
index
)
var
values
[][]
byte
func
QueryCompletedOrderList
(
localdb
dbm
.
KVDB
,
left
,
right
*
et
.
Asset
,
primaryKey
string
,
count
,
direction
int32
)
(
types
.
Message
,
error
)
{
table
:=
NewCompletedOrderTable
(
localdb
)
query
:=
table
.
GetQuery
(
localdb
)
prefix
:=
[]
byte
(
fmt
.
Sprintf
(
"%s:%s"
,
left
.
Symbol
,
right
.
Symbol
))
if
count
==
0
{
count
=
et
.
Count
}
var
rows
[]
*
Row
var
err
error
if
index
==
0
{
//第一次查询,默认展示最新得成交记录
values
,
err
=
localdb
.
List
(
prefix
,
nil
,
count
,
direction
)
if
primaryKey
==
""
{
//第一次查询,默认展示最新得成交记录
rows
,
err
=
query
.
ListIndex
(
"index"
,
prefix
,
nil
,
count
,
direction
)
}
else
{
values
,
err
=
localdb
.
List
(
prefix
,
key
,
count
,
direction
)
rows
,
err
=
query
.
ListIndex
(
"index"
,
prefix
,
[]
byte
(
primaryKey
)
,
count
,
direction
)
}
if
err
!=
nil
{
elog
.
Error
(
"QueryCompletedOrderList."
,
"left"
,
left
,
"right"
,
right
,
"err"
,
err
.
Error
())
return
nil
,
err
}
var
list
[]
*
et
.
OrderID
for
_
,
value
:=
range
values
{
var
orderID
et
.
OrderID
err
:=
types
.
Decode
(
value
,
&
orderID
)
if
err
!=
nil
{
elog
.
Warn
(
"QueryCompletedOrderList.Decode"
,
"marketDept"
,
"err"
,
err
.
Error
())
continue
}
list
=
append
(
list
,
&
orderID
)
}
var
orderList
et
.
OrderList
for
_
,
orderID
:=
range
list
{
order
,
err
:=
findOrderByOrderID
(
statedb
,
orderID
.
ID
)
if
err
!=
nil
{
continue
}
//替换索引index
order
.
Index
=
orderID
.
Index
for
_
,
row
:=
range
rows
{
order
:=
row
.
Data
.
(
*
et
.
Order
)
//替换已经成交得量
order
.
Executed
=
order
.
GetLimitOrder
()
.
Amount
-
order
.
Balance
orderList
.
List
=
append
(
orderList
.
List
,
order
)
}
//设置主键索引
if
len
(
rows
)
==
int
(
count
)
{
orderList
.
PrimaryKey
=
string
(
rows
[
len
(
rows
)
-
1
]
.
Primary
)
}
return
&
orderList
,
nil
}
//QueryOrderList,默认展示最新的
func
QueryOrderList
(
localdb
dbm
.
Lister
,
statedb
dbm
.
KV
,
addr
string
,
status
,
count
,
direction
int32
,
index
int64
)
(
types
.
Message
,
error
)
{
prefix
:=
calcUserOrderIDPrefix
(
status
,
addr
)
key
:=
calcUserOrderIDKey
(
status
,
addr
,
index
)
var
values
[][]
byte
func
QueryOrderList
(
localdb
dbm
.
KVDB
,
statedb
dbm
.
KV
,
addr
string
,
status
,
count
,
direction
int32
,
primaryKey
string
)
(
types
.
Message
,
error
)
{
table
:=
NewUserOrderTable
(
localdb
)
query
:=
table
.
GetQuery
(
localdb
)
prefix
:=
[]
byte
(
fmt
.
Sprintf
(
"%s:%d"
,
addr
,
status
))
if
count
==
0
{
count
=
et
.
Count
}
var
rows
[]
*
Row
var
err
error
if
index
==
0
{
//第一次查询,默认展示最新得成交记录
values
,
err
=
localdb
.
List
(
prefix
,
nil
,
count
,
direction
)
if
primaryKey
==
""
{
//第一次查询,默认展示最新得成交记录
rows
,
err
=
query
.
ListIndex
(
"index"
,
prefix
,
nil
,
count
,
direction
)
}
else
{
values
,
err
=
localdb
.
List
(
prefix
,
key
,
count
,
direction
)
rows
,
err
=
query
.
ListIndex
(
"index"
,
prefix
,
[]
byte
(
primaryKey
)
,
count
,
direction
)
}
if
err
!=
nil
{
elog
.
Error
(
"QueryOrderList."
,
"addr"
,
addr
,
"err"
,
err
.
Error
())
return
nil
,
err
}
var
list
[]
*
et
.
OrderID
for
_
,
value
:=
range
values
{
var
orderID
et
.
OrderID
err
:=
types
.
Decode
(
value
,
&
orderID
)
if
err
!=
nil
{
elog
.
Warn
(
"QueryOrderList.Decode"
,
"marketDept"
,
"err"
,
err
.
Error
())
continue
}
list
=
append
(
list
,
&
orderID
)
}
var
orderList
et
.
OrderList
for
_
,
orderID
:=
range
list
{
order
,
err
:=
findOrderByOrderID
(
statedb
,
orderID
.
ID
)
if
err
!=
nil
{
continue
}
//替换索引index
order
.
Index
=
orderID
.
Index
for
_
,
row
:=
range
rows
{
order
:=
row
.
Data
.
(
*
et
.
Order
)
//替换已经成交得量
order
.
Executed
=
order
.
GetLimitOrder
()
.
Amount
-
order
.
Balance
orderList
.
List
=
append
(
orderList
.
List
,
order
)
}
//设置主键索引
if
len
(
rows
)
==
int
(
count
)
{
orderList
.
PrimaryKey
=
string
(
rows
[
len
(
rows
)
-
1
]
.
Primary
)
}
return
&
orderList
,
nil
}
func
queryMarketDepth
(
localdb
dbm
.
KVDB
,
left
,
right
*
et
.
Asset
,
op
int32
,
price
float64
)
(
*
et
.
MarketDepth
,
error
)
{
table
:=
NewMarketDepthTable
(
localdb
)
primaryKey
:=
[]
byte
(
fmt
.
Sprintf
(
"%s:%s:%d:%016d"
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
op
,
int64
(
Truncate
(
price
)
*
float64
(
1e8
))))
row
,
err
:=
table
.
GetData
(
primaryKey
)
if
err
!=
nil
{
return
nil
,
err
}
return
row
.
Data
.
(
*
et
.
MarketDepth
),
nil
}
//截取小数点后8位
func
Truncate
(
price
float64
)
float64
{
return
math
.
Trunc
(
float64
(
1e8
)
*
price
)
/
float64
(
1e8
)
...
...
plugin/dapp/exchange/executor/exec_local.go
View file @
ef3012f1
...
...
@@ -2,7 +2,7 @@ package executor
import
(
"github.com/33cn/chain33/types"
e
xchangetypes
"github.com/33cn/plugin/plugin/dapp/exchange/types"
e
ty
"github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
...
...
@@ -10,13 +10,13 @@ import (
* 非关键数据,本地存储(localDB), 用于辅助查询,效率高
*/
func
(
e
*
exchange
)
ExecLocal_LimitOrder
(
payload
*
e
xchangetypes
.
LimitOrder
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
e
*
exchange
)
ExecLocal_LimitOrder
(
payload
*
e
ty
.
LimitOrder
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
if
receiptData
.
Ty
==
types
.
ExecOk
{
for
_
,
log
:=
range
receiptData
.
Logs
{
switch
log
.
Ty
{
case
e
xchangetypes
.
TyLimitOrderLog
:
receipt
:=
&
e
xchangetypes
.
ReceiptExchange
{}
case
e
ty
.
TyLimitOrderLog
:
receipt
:=
&
e
ty
.
ReceiptExchange
{}
if
err
:=
types
.
Decode
(
log
.
Log
,
receipt
);
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -28,13 +28,13 @@ func (e *exchange) ExecLocal_LimitOrder(payload *exchangetypes.LimitOrder, tx *t
return
e
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
e
*
exchange
)
ExecLocal_MarketOrder
(
payload
*
e
xchangetypes
.
MarketOrder
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
e
*
exchange
)
ExecLocal_MarketOrder
(
payload
*
e
ty
.
MarketOrder
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
if
receiptData
.
Ty
==
types
.
ExecOk
{
for
_
,
log
:=
range
receiptData
.
Logs
{
switch
log
.
Ty
{
case
e
xchangetypes
.
TyMarketOrderLog
:
receipt
:=
&
e
xchangetypes
.
ReceiptExchange
{}
case
e
ty
.
TyMarketOrderLog
:
receipt
:=
&
e
ty
.
ReceiptExchange
{}
if
err
:=
types
.
Decode
(
log
.
Log
,
receipt
);
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -46,13 +46,13 @@ func (e *exchange) ExecLocal_MarketOrder(payload *exchangetypes.MarketOrder, tx
return
e
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
e
*
exchange
)
ExecLocal_RevokeOrder
(
payload
*
e
xchangetypes
.
RevokeOrder
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
e
*
exchange
)
ExecLocal_RevokeOrder
(
payload
*
e
ty
.
RevokeOrder
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
if
receiptData
.
Ty
==
types
.
ExecOk
{
for
_
,
log
:=
range
receiptData
.
Logs
{
switch
log
.
Ty
{
case
e
xchangetypes
.
TyRevokeOrderLog
:
receipt
:=
&
e
xchangetypes
.
ReceiptExchange
{}
case
e
ty
.
TyRevokeOrderLog
:
receipt
:=
&
e
ty
.
ReceiptExchange
{}
if
err
:=
types
.
Decode
(
log
.
Log
,
receipt
);
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -72,18 +72,21 @@ func (e *exchange) addAutoRollBack(tx *types.Transaction, kv []*types.KeyValue)
return
dbSet
}
func
(
e
*
exchange
)
updateIndex
(
receipt
*
exchangetypes
.
ReceiptExchange
)
(
kvs
[]
*
types
.
KeyValue
)
{
func
(
e
*
exchange
)
updateIndex
(
receipt
*
ety
.
ReceiptExchange
)
(
kvs
[]
*
types
.
KeyValue
)
{
completedTable
:=
NewCompletedOrderTable
(
e
.
GetLocalDB
())
marketTable
:=
NewMarketDepthTable
(
e
.
GetLocalDB
())
userTable
:=
NewUserOrderTable
(
e
.
GetLocalDB
())
orderTable
:=
NewMarketOrderTable
(
e
.
GetLocalDB
())
switch
receipt
.
Order
.
Status
{
case
e
xchangetypes
.
Ordered
:
case
e
ty
.
Ordered
:
left
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetLeftAsset
()
right
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetRightAsset
()
op
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetOp
()
price
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetPrice
()
o
derID
:=
receipt
.
GetOrder
()
.
OrderID
o
rder
:=
receipt
.
GetOrder
()
index
:=
receipt
.
GetIndex
()
addr
:=
receipt
.
GetOrder
()
.
Addr
var
markDepth
exchangetypes
.
MarketDepth
err
:=
findObject
(
e
.
GetLocalDB
(),
calcMarketDepthKey
(
left
,
right
,
op
,
price
),
&
markDepth
)
var
markDepth
ety
.
MarketDepth
depth
,
err
:=
queryMarketDepth
(
e
.
GetLocalDB
(),
left
,
right
,
op
,
price
)
if
err
==
types
.
ErrNotFound
{
markDepth
.
Price
=
price
markDepth
.
LeftAsset
=
left
...
...
@@ -95,38 +98,61 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
markDepth
.
LeftAsset
=
left
markDepth
.
RightAsset
=
right
markDepth
.
Op
=
op
markDepth
.
Amount
=
markD
epth
.
Amount
+
receipt
.
Order
.
Balance
markDepth
.
Amount
=
d
epth
.
Amount
+
receipt
.
Order
.
Balance
}
//marketDepth
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
op
,
price
),
Value
:
types
.
Encode
(
&
markDepth
)})
//orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthOrderKey
(
left
,
right
,
op
,
price
,
receipt
.
Index
),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
oderID
,
Index
:
index
})})
//addr orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Ordered
,
addr
,
index
),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
oderID
,
Index
:
index
})})
err
=
marketTable
.
Replace
(
&
markDepth
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"marketTable.Replace"
,
err
.
Error
())
return
nil
}
err
=
orderTable
.
Replace
(
order
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"orderTable.Replace"
,
err
.
Error
())
return
nil
}
err
=
userTable
.
Replace
(
order
)
if
err
!=
nil
{
return
nil
}
if
len
(
receipt
.
MatchOrders
)
>
0
{
//撮合交易更新
cache
:=
make
(
map
[
float64
]
int64
)
for
i
,
matchOrder
:=
range
receipt
.
MatchOrders
{
if
matchOrder
.
Status
==
e
xchangetypes
.
Completed
{
if
matchOrder
.
Status
==
e
ty
.
Completed
{
// 删除原有状态orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthOrderKey
(
left
,
right
,
matchOrder
.
GetLimitOrder
()
.
Op
,
matchOrder
.
GetLimitOrder
()
.
Price
,
matchOrder
.
Index
),
Value
:
nil
})
err
=
orderTable
.
DelRow
(
matchOrder
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"orderTable.DelRow"
,
err
.
Error
())
return
nil
}
//删除原有状态orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Ordered
,
matchOrder
.
Addr
,
matchOrder
.
Index
),
Value
:
nil
})
matchOrder
.
Status
=
ety
.
Ordered
userTable
.
DelRow
(
matchOrder
)
//更新状态为已完成,索引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
)})})
matchOrder
.
Status
=
ety
.
Completed
matchOrder
.
Index
=
index
+
int64
(
i
+
1
)
userTable
.
Replace
(
matchOrder
)
//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
)})})
completedTable
.
Replace
(
matchOrder
)
}
if
matchOrder
.
Status
==
ety
.
Ordered
{
//更新数据
err
=
orderTable
.
Replace
(
matchOrder
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"orderTable.Replace"
,
err
.
Error
())
return
nil
}
}
executed
:=
cache
[
matchOrder
.
GetLimitOrder
()
.
Price
]
executed
=
executed
+
matchOrder
.
Executed
cache
[
matchOrder
.
GetLimitOrder
()
.
Price
]
=
executed
}
//更改匹配市场深度
for
pr
,
executed
:=
range
cache
{
var
matchDepth
e
xchangetypes
.
MarketDepth
err
=
findObject
(
e
.
GetLocalDB
(),
calcMarketDepthKey
(
left
,
right
,
OpSwap
(
op
),
pr
),
&
matchDepth
)
var
matchDepth
e
ty
.
MarketDepth
depth
,
err
:=
queryMarketDepth
(
e
.
GetLocalDB
(),
left
,
right
,
OpSwap
(
op
),
pr
)
if
err
==
types
.
ErrNotFound
{
continue
}
else
{
...
...
@@ -134,46 +160,80 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
matchDepth
.
LeftAsset
=
left
matchDepth
.
RightAsset
=
right
matchDepth
.
Op
=
OpSwap
(
op
)
matchDepth
.
Amount
=
matchD
epth
.
Amount
-
executed
matchDepth
.
Amount
=
d
epth
.
Amount
-
executed
}
//marketDepth
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
OpSwap
(
op
),
price
),
Value
:
types
.
Encode
(
&
matchDepth
)})
err
=
marketTable
.
Replace
(
&
matchDepth
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"marketTable.Replace"
,
err
.
Error
())
return
nil
}
if
matchDepth
.
Amount
<=
0
{
//删除
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
OpSwap
(
op
),
price
),
Value
:
nil
})
err
=
marketTable
.
DelRow
(
&
matchDepth
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"marketTable.DelRow"
,
err
.
Error
())
return
nil
}
}
}
}
return
case
exchangetypes
.
Completed
:
case
ety
.
Completed
:
left
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetLeftAsset
()
right
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetRightAsset
()
op
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetOp
()
price
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetPrice
()
oderID
:=
receipt
.
GetOrder
()
.
OrderID
index
:=
receipt
.
GetIndex
()
addr
:=
receipt
.
GetOrder
()
.
Addr
//user orderID
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
})})
err
:=
userTable
.
Replace
(
receipt
.
GetOrder
())
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"userTable.Replace"
,
err
.
Error
())
return
nil
}
err
=
completedTable
.
Replace
(
receipt
.
Order
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"completedTable.Replace"
,
err
.
Error
())
return
nil
}
cache
:=
make
(
map
[
float64
]
int64
)
if
len
(
receipt
.
MatchOrders
)
>
0
{
//撮合交易更新
for
i
,
matchOrder
:=
range
receipt
.
MatchOrders
{
if
matchOrder
.
Status
==
e
xchangetypes
.
Completed
{
if
matchOrder
.
Status
==
e
ty
.
Completed
{
// 删除原有状态orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthOrderKey
(
left
,
right
,
matchOrder
.
GetLimitOrder
()
.
Op
,
price
,
matchOrder
.
Index
),
Value
:
nil
})
err
=
orderTable
.
DelRow
(
matchOrder
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"orderTable.DelRow"
,
err
.
Error
())
return
nil
}
//删除原有状态orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Ordered
,
matchOrder
.
Addr
,
matchOrder
.
Index
),
Value
:
nil
})
matchOrder
.
Status
=
ety
.
Ordered
err
=
userTable
.
DelRow
(
matchOrder
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"userTable.DelRow"
,
err
.
Error
())
return
nil
}
//更新状态为已完成,更新索引
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
)})})
matchOrder
.
Status
=
ety
.
Completed
matchOrder
.
Index
=
index
+
int64
(
i
+
1
)
err
=
userTable
.
Replace
(
matchOrder
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"userTable.Replace"
,
err
.
Error
())
return
nil
}
//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
)})})
err
=
completedTable
.
Replace
(
matchOrder
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"completedTable.Replace"
,
err
.
Error
())
return
nil
}
}
if
matchOrder
.
Status
==
ety
.
Ordered
{
//更新数据
err
=
orderTable
.
Replace
(
matchOrder
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"orderTable.Replace"
,
err
.
Error
())
return
nil
}
}
executed
:=
cache
[
matchOrder
.
GetLimitOrder
()
.
Price
]
executed
=
executed
+
matchOrder
.
Executed
...
...
@@ -181,8 +241,8 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
}
//更改match市场深度
for
pr
,
executed
:=
range
cache
{
var
matchDepth
e
xchangetypes
.
MarketDepth
err
:=
findObject
(
e
.
GetLocalDB
(),
calcMarketDepthKey
(
left
,
right
,
OpSwap
(
op
),
pr
),
&
matchDepth
)
var
matchDepth
e
ty
.
MarketDepth
depth
,
err
:=
queryMarketDepth
(
e
.
GetLocalDB
(),
left
,
right
,
OpSwap
(
op
),
pr
)
if
err
==
types
.
ErrNotFound
{
continue
}
else
{
...
...
@@ -190,51 +250,105 @@ func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*t
matchDepth
.
LeftAsset
=
left
matchDepth
.
RightAsset
=
right
matchDepth
.
Op
=
OpSwap
(
op
)
matchDepth
.
Amount
=
matchD
epth
.
Amount
-
executed
matchDepth
.
Amount
=
d
epth
.
Amount
-
executed
}
//marketDepth
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
OpSwap
(
op
),
price
),
Value
:
types
.
Encode
(
&
matchDepth
)})
err
=
marketTable
.
Replace
(
&
matchDepth
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"marketTable.Replace"
,
err
.
Error
())
return
nil
}
if
matchDepth
.
Amount
<=
0
{
//删除
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
OpSwap
(
op
),
price
),
Value
:
nil
})
err
=
marketTable
.
DelRow
(
&
matchDepth
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"marketTable.DelRow"
,
err
.
Error
())
return
nil
}
}
}
}
return
case
exchangetypes
.
Revoked
:
case
ety
.
Revoked
:
//只有状态时ordered状态的订单才能被撤回
left
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetLeftAsset
()
right
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetRightAsset
()
op
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetOp
()
price
:=
receipt
.
GetOrder
()
.
GetLimitOrder
()
.
GetPrice
()
o
derID
:=
receipt
.
GetOrder
()
.
OrderID
o
rder
:=
receipt
.
GetOrder
()
index
:=
receipt
.
GetIndex
()
addr
:=
receipt
.
GetOrder
()
.
Addr
var
marketDepth
exchangetypes
.
MarketDepth
err
:=
findObject
(
e
.
GetLocalDB
(),
calcMarketDepthKey
(
left
,
right
,
op
,
price
),
&
marketDepth
)
var
marketDepth
ety
.
MarketDepth
depth
,
err
:=
queryMarketDepth
(
e
.
GetLocalDB
(),
left
,
right
,
op
,
price
)
if
err
==
nil
{
//marketDepth
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
)})
marketDepth
.
Amount
=
depth
.
Amount
-
receipt
.
GetOrder
()
.
Balance
err
=
marketTable
.
Replace
(
&
marketDepth
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"marketTable.Replace"
,
err
.
Error
())
return
nil
}
}
elog
.
Error
(
"revoked"
,
"marketDepth.Amount"
,
marketDepth
.
Amount
)
if
marketDepth
.
Amount
==
0
{
//删除
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthKey
(
left
,
right
,
op
,
price
),
Value
:
nil
})
err
=
marketTable
.
DelRow
(
&
marketDepth
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"marketTable.DelRow"
,
err
.
Error
())
return
nil
}
}
// 删除原有状态orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcMarketDepthOrderKey
(
left
,
right
,
op
,
price
,
receipt
.
GetOrder
()
.
Index
),
Value
:
nil
})
err
=
orderTable
.
DelRow
(
order
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"orderTable.DelRow"
,
err
.
Error
())
return
nil
}
//删除原有状态orderID
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Ordered
,
addr
,
receipt
.
GetOrder
()
.
Index
),
Value
:
nil
})
order
.
Status
=
ety
.
Ordered
err
=
userTable
.
DelRow
(
order
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"userTable.DelRow"
,
err
.
Error
())
return
nil
}
order
.
Status
=
ety
.
Revoked
order
.
Index
=
index
//添加撤销的订单
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
calcUserOrderIDKey
(
exchangetypes
.
Revoked
,
addr
,
index
),
Value
:
types
.
Encode
(
&
exchangetypes
.
OrderID
{
ID
:
oderID
,
Index
:
index
})})
err
=
userTable
.
Replace
(
order
)
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"userTable.Replace"
,
err
.
Error
())
return
nil
}
}
kv
,
err
:=
marketTable
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"marketTable.Save"
,
err
.
Error
())
return
nil
}
kvs
=
append
(
kvs
,
kv
...
)
kv
,
err
=
userTable
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"userTable.Save"
,
err
.
Error
())
return
nil
}
kvs
=
append
(
kvs
,
kv
...
)
kv
,
err
=
orderTable
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"orderTable.Save"
,
err
.
Error
())
return
nil
}
kvs
=
append
(
kvs
,
kv
...
)
kv
,
err
=
completedTable
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"updateIndex"
,
"completedTable.Save"
,
err
.
Error
())
return
nil
}
kvs
=
append
(
kvs
,
kv
...
)
return
}
func
OpSwap
(
op
int32
)
int32
{
if
op
==
e
xchangetypes
.
OpBuy
{
return
e
xchangetypes
.
OpSell
if
op
==
e
ty
.
OpBuy
{
return
e
ty
.
OpSell
}
return
e
xchangetypes
.
OpBuy
return
e
ty
.
OpBuy
}
plugin/dapp/exchange/executor/kv.go
deleted
100644 → 0
View file @
ca3650a2
package
executor
import
(
"fmt"
"github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
* 用户合约存取kv数据时,key值前缀需要满足一定规范
* 即key = keyPrefix + userKey
* 需要字段前缀查询时,使用’-‘作为分割符号
*/
var
(
//KeyPrefixStateDB state db key必须前缀
KeyPrefixStateDB
=
"mavl-exchange-"
//KeyPrefixLocalDB local db的key必须前缀
KeyPrefixLocalDB
=
"LODB-exchange-"
)
//状态数据库中存储具体挂单信息
func
calcOrderKey
(
orderID
string
)
[]
byte
{
key
:=
fmt
.
Sprintf
(
"%s"
+
"orderID:%s"
,
KeyPrefixStateDB
,
orderID
)
return
[]
byte
(
key
)
}
func
calcMarketDepthPrefix
(
left
,
right
*
types
.
Asset
,
op
int32
)
[]
byte
{
key
:=
fmt
.
Sprintf
(
"%s"
+
"depth-%s-%s-%d:"
,
KeyPrefixLocalDB
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
op
)
return
[]
byte
(
key
)
}
//市场深度
func
calcMarketDepthKey
(
left
,
right
*
types
.
Asset
,
op
int32
,
price
float64
)
[]
byte
{
// 设置精度为1e8
key
:=
fmt
.
Sprintf
(
"%s"
+
"depth-%s-%s-%d:%016d"
,
KeyPrefixLocalDB
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
op
,
int64
(
Truncate
(
price
)
*
float64
(
1e8
)))
return
[]
byte
(
key
)
}
func
calcMarketDepthOrderPrefix
(
left
,
right
*
types
.
Asset
,
op
int32
,
price
float64
)
[]
byte
{
// 设置精度为1e8
key
:=
fmt
.
Sprintf
(
"%s"
+
"order-%s-%s-%d:%016d"
,
KeyPrefixLocalDB
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
op
,
int64
(
Truncate
(
price
)
*
float64
(
1e8
)))
return
[]
byte
(
key
)
}
// localdb中存储市场挂单ID
func
calcMarketDepthOrderKey
(
left
,
right
*
types
.
Asset
,
op
int32
,
price
float64
,
index
int64
)
[]
byte
{
// 设置精度为1e8
key
:=
fmt
.
Sprintf
(
"%s"
+
"order-%s-%s-%d:%016d:%022d"
,
KeyPrefixLocalDB
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
op
,
int64
(
Truncate
(
price
)
*
float64
(
1e8
)),
index
)
return
[]
byte
(
key
)
}
//最新已经成交的订单,这里状态固定都是完成状态,这个主要给外部使用,可以查询最新得成交信息,存在多个情况
//matchOrderIndex,是匹配order在数组中的index,这里预留4个0000,用来解决同一笔交易中存在key重复得情况,这样设计保证了key得唯一性
func
calcCompletedOrderKey
(
left
,
right
*
types
.
Asset
,
index
int64
)
[]
byte
{
// 设置精度为1e8
key
:=
fmt
.
Sprintf
(
"%s"
+
"completed-%s-%s-%d:%022d"
,
KeyPrefixLocalDB
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
types
.
Completed
,
index
)
return
[]
byte
(
key
)
}
func
calcCompletedOrderPrefix
(
left
,
right
*
types
.
Asset
)
[]
byte
{
// 设置精度为1e8
key
:=
fmt
.
Sprintf
(
"%s"
+
"completed-%s-%s-%d:"
,
KeyPrefixLocalDB
,
left
.
GetSymbol
(),
right
.
GetSymbol
(),
types
.
Completed
)
return
[]
byte
(
key
)
}
//根据地址和订单状态,去查询订单列表,包含所有交易对
func
calcUserOrderIDPrefix
(
status
int32
,
addr
string
)
[]
byte
{
key
:=
fmt
.
Sprintf
(
"%s"
+
"addr:%s:%d:"
,
KeyPrefixLocalDB
,
addr
,
status
)
return
[]
byte
(
key
)
}
//matchOrderIndex,用来解决同一笔交易中存在key重复得情况,这样设计保证了key得唯一性
func
calcUserOrderIDKey
(
status
int32
,
addr
string
,
index
int64
)
[]
byte
{
key
:=
fmt
.
Sprintf
(
"%s"
+
"addr:%s:%d:%022d"
,
KeyPrefixLocalDB
,
addr
,
status
,
index
)
return
[]
byte
(
key
)
}
plugin/dapp/exchange/executor/query.go
View file @
ef3012f1
...
...
@@ -20,7 +20,7 @@ func (s *exchange) Query_QueryMarketDepth(in *et.QueryMarketDepth) (types.Messag
if
!
CheckOp
(
in
.
Op
)
{
return
nil
,
et
.
ErrAssetOp
}
return
QueryMarketDepth
(
s
.
GetLocalDB
(),
in
.
LeftAsset
,
in
.
RightAsset
,
in
.
Op
,
in
.
Pri
ce
,
in
.
Count
)
return
QueryMarketDepth
(
s
.
GetLocalDB
(),
in
.
LeftAsset
,
in
.
RightAsset
,
in
.
Op
,
in
.
Pri
maryKey
,
in
.
Count
)
}
//查询已经完成得订单
...
...
@@ -35,15 +35,15 @@ func (s *exchange) Query_QueryCompletedOrderList(in *et.QueryCompletedOrderList)
if
!
CheckDirection
(
in
.
Direction
)
{
return
nil
,
et
.
ErrDirection
}
return
QueryCompletedOrderList
(
s
.
GetLocalDB
(),
s
.
GetStateDB
(),
in
.
LeftAsset
,
in
.
RightAsset
,
in
.
Index
,
in
.
Count
,
in
.
Direction
)
return
QueryCompletedOrderList
(
s
.
GetLocalDB
(),
in
.
LeftAsset
,
in
.
RightAsset
,
in
.
PrimaryKey
,
in
.
Count
,
in
.
Direction
)
}
//根据orderID查询订单信息
func
(
s
*
exchange
)
Query_QueryOrder
(
in
*
et
.
QueryOrder
)
(
types
.
Message
,
error
)
{
if
in
.
OrderID
==
""
{
if
in
.
OrderID
==
0
{
return
nil
,
et
.
ErrOrderID
}
return
findOrderByOrderID
(
s
.
GetStateDB
(),
in
.
OrderID
)
return
findOrderByOrderID
(
s
.
GetStateDB
(),
s
.
GetLocalDB
(),
in
.
OrderID
)
}
//根据订单状态,查询订单信息(这里面包含所有交易对)
...
...
@@ -62,5 +62,5 @@ func (s *exchange) Query_QueryOrderList(in *et.QueryOrderList) (types.Message, e
if
in
.
Address
==
""
{
return
nil
,
et
.
ErrAddr
}
return
QueryOrderList
(
s
.
GetLocalDB
(),
s
.
GetStateDB
(),
in
.
Address
,
in
.
Status
,
in
.
Count
,
in
.
Direction
,
in
.
Index
)
return
QueryOrderList
(
s
.
GetLocalDB
(),
s
.
GetStateDB
(),
in
.
Address
,
in
.
Status
,
in
.
Count
,
in
.
Direction
,
in
.
PrimaryKey
)
}
plugin/dapp/exchange/executor/tables.go
0 → 100644
View file @
ef3012f1
package
executor
import
(
"fmt"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
ety
"github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
* 用户合约存取kv数据时,key值前缀需要满足一定规范
* 即key = keyPrefix + userKey
* 需要字段前缀查询时,使用’-‘作为分割符号
*/
const
(
//KeyPrefixStateDB state db key必须前缀
KeyPrefixStateDB
=
"mavl-exchange-"
//KeyPrefixLocalDB local db的key必须前缀
KeyPrefixLocalDB
=
"LODB-exchange"
)
//状态数据库中存储具体挂单信息
func
calcOrderKey
(
orderID
int64
)
[]
byte
{
key
:=
fmt
.
Sprintf
(
"%s"
+
"orderID:%022d"
,
KeyPrefixStateDB
,
orderID
)
return
[]
byte
(
key
)
}
var
opt_exchange_depth
=
&
table
.
Option
{
Prefix
:
KeyPrefixLocalDB
,
Name
:
"depth"
,
Primary
:
"price"
,
Index
:
nil
,
}
//重新设计表,list查询全部在订单信息localdb查询中
var
opt_exchange_order
=
&
table
.
Option
{
Prefix
:
KeyPrefixLocalDB
,
Name
:
"order"
,
Primary
:
"orderID"
,
Index
:
[]
string
{
"market_order"
},
}
//根据地址和状态,index是实时在变化,要有先后顺序
var
opt_exchange_user_order
=
&
table
.
Option
{
Prefix
:
KeyPrefixLocalDB
,
Name
:
"UserOrder"
,
Primary
:
"index"
,
Index
:
nil
,
}
var
opt_exchange_completed
=
&
table
.
Option
{
Prefix
:
KeyPrefixLocalDB
,
Name
:
"completed"
,
Primary
:
"index"
,
Index
:
nil
,
}
//NewTable 新建表
func
NewMarketDepthTable
(
kvdb
db
.
KV
)
*
table
.
Table
{
rowmeta
:=
NewMarketDepthRow
()
table
,
err
:=
table
.
NewTable
(
rowmeta
,
kvdb
,
opt_exchange_depth
)
if
err
!=
nil
{
panic
(
err
)
}
return
table
}
func
NewMarketOrderTable
(
kvdb
db
.
KV
)
*
table
.
Table
{
rowmeta
:=
NewOrderRow
()
table
,
err
:=
table
.
NewTable
(
rowmeta
,
kvdb
,
opt_exchange_order
)
if
err
!=
nil
{
panic
(
err
)
}
return
table
}
func
NewUserOrderTable
(
kvdb
db
.
KV
)
*
table
.
Table
{
rowmeta
:=
NewUserOrderRow
()
table
,
err
:=
table
.
NewTable
(
rowmeta
,
kvdb
,
opt_exchange_user_order
)
if
err
!=
nil
{
panic
(
err
)
}
return
table
}
func
NewCompletedOrderTable
(
kvdb
db
.
KV
)
*
table
.
Table
{
rowmeta
:=
NewCompletedOrderRow
()
table
,
err
:=
table
.
NewTable
(
rowmeta
,
kvdb
,
opt_exchange_completed
)
if
err
!=
nil
{
panic
(
err
)
}
return
table
}
//OrderRow table meta 结构
type
OrderRow
struct
{
*
ety
.
Order
}
//NewOrderRow 新建一个meta 结构
func
NewOrderRow
()
*
OrderRow
{
return
&
OrderRow
{
Order
:
&
ety
.
Order
{}}
}
//CreateRow
func
(
r
*
OrderRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
ety
.
Order
{}}
}
//SetPayload 设置数据
func
(
r
*
OrderRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
txdata
,
ok
:=
data
.
(
*
ety
.
Order
);
ok
{
r
.
Order
=
txdata
return
nil
}
return
types
.
ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func
(
r
*
OrderRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
key
==
"orderID"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%022d"
,
r
.
OrderID
)),
nil
}
else
if
key
==
"market_order"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%s:%s:%d:%016d"
,
r
.
GetLimitOrder
()
.
LeftAsset
.
GetSymbol
(),
r
.
GetLimitOrder
()
.
RightAsset
.
GetSymbol
(),
r
.
GetLimitOrder
()
.
Op
,
int64
(
Truncate
(
r
.
GetLimitOrder
()
.
Price
*
float64
(
1e8
))))),
nil
}
return
nil
,
types
.
ErrNotFound
}
//UserOrderRow table meta 结构
type
UserOrderRow
struct
{
*
ety
.
Order
}
//NewOrderRow 新建一个meta 结构
func
NewUserOrderRow
()
*
UserOrderRow
{
return
&
UserOrderRow
{
Order
:
&
ety
.
Order
{
Value
:
&
ety
.
Order_LimitOrder
{
LimitOrder
:
&
ety
.
LimitOrder
{}}}}
}
//CreateRow
func
(
r
*
UserOrderRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
ety
.
Order
{}}
}
//SetPayload 设置数据
func
(
r
*
UserOrderRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
txdata
,
ok
:=
data
.
(
*
ety
.
Order
);
ok
{
r
.
Order
=
txdata
return
nil
}
return
types
.
ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func
(
r
*
UserOrderRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
key
==
"index"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%s:%d:%022d"
,
r
.
Addr
,
r
.
Status
,
r
.
Index
)),
nil
}
return
nil
,
types
.
ErrNotFound
}
//CompletedOrderRow table meta 结构
type
CompletedOrderRow
struct
{
*
ety
.
Order
}
func
NewCompletedOrderRow
()
*
CompletedOrderRow
{
return
&
CompletedOrderRow
{
Order
:
&
ety
.
Order
{
Value
:
&
ety
.
Order_LimitOrder
{
LimitOrder
:
&
ety
.
LimitOrder
{}}}}
}
func
(
m
*
CompletedOrderRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
ety
.
Order
{
Value
:
&
ety
.
Order_LimitOrder
{
LimitOrder
:
&
ety
.
LimitOrder
{}}}}
}
//SetPayload 设置数据
func
(
m
*
CompletedOrderRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
txdata
,
ok
:=
data
.
(
*
ety
.
Order
);
ok
{
m
.
Order
=
txdata
return
nil
}
return
types
.
ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func
(
m
*
CompletedOrderRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
key
==
"index"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%s:%s:%022d"
,
m
.
GetLimitOrder
()
.
LeftAsset
.
GetSymbol
(),
m
.
GetLimitOrder
()
.
RightAsset
.
GetSymbol
(),
m
.
Index
)),
nil
}
return
nil
,
types
.
ErrNotFound
}
//marketDepthRow table meta 结构
type
MarketDepthRow
struct
{
*
ety
.
MarketDepth
}
//NewOracleRow 新建一个meta 结构
func
NewMarketDepthRow
()
*
MarketDepthRow
{
return
&
MarketDepthRow
{
MarketDepth
:
&
ety
.
MarketDepth
{}}
}
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存eventid)
func
(
m
*
MarketDepthRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
ety
.
MarketDepth
{}}
}
//SetPayload 设置数据
func
(
m
*
MarketDepthRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
txdata
,
ok
:=
data
.
(
*
ety
.
MarketDepth
);
ok
{
m
.
MarketDepth
=
txdata
return
nil
}
return
types
.
ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func
(
m
*
MarketDepthRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
key
==
"price"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%s:%s:%d:%016d"
,
m
.
LeftAsset
.
GetSymbol
(),
m
.
RightAsset
.
GetSymbol
(),
m
.
Op
,
int64
(
Truncate
(
m
.
Price
)
*
float64
(
1e8
)))),
nil
}
return
nil
,
types
.
ErrNotFound
}
plugin/dapp/exchange/proto/exchange.proto
View file @
ef3012f1
...
...
@@ -41,7 +41,7 @@ message MarketOrder {
//撤回订单
message
RevokeOrder
{
//订单号
string
orderID
=
1
;
int64
orderID
=
1
;
}
//资产类型
message
asset
{
...
...
@@ -51,7 +51,7 @@ message asset {
//订单信息
message
Order
{
string
orderID
=
1
;
int64
orderID
=
1
;
oneof
value
{
LimitOrder
limitOrder
=
2
;
MarketOrder
marketOrder
=
3
;
...
...
@@ -72,16 +72,6 @@ message Order {
int64
index
=
10
;
}
//挂单价
message
OrderPrice
{
double
price
=
1
;
int64
index
=
2
;
}
//单号
message
OrderID
{
string
ID
=
1
;
int64
index
=
2
;
}
//查询接口
message
QueryMarketDepth
{
//资产1
...
...
@@ -91,7 +81,7 @@ message QueryMarketDepth {
//操作, 1为买,2为卖
int32
op
=
3
;
// 这里用价格作为索引值
double
price
=
4
;
string
primaryKey
=
4
;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32
count
=
5
;
}
...
...
@@ -111,6 +101,7 @@ message MarketDepth {
//查询接口返回的市场深度列表
message
MarketDepthList
{
repeated
MarketDepth
list
=
1
;
string
primaryKey
=
2
;
}
//查询最新得成交信息,外部接口
...
...
@@ -120,7 +111,7 @@ message QueryCompletedOrderList {
//资产2
asset
rightAsset
=
2
;
// 索引值
int64
index
=
3
;
string
primaryKey
=
3
;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32
count
=
4
;
// 0降序,1升序,默认降序
...
...
@@ -129,7 +120,7 @@ message QueryCompletedOrderList {
//根据orderID去查询订单信息
message
QueryOrder
{
string
orderID
=
1
;
int64
orderID
=
1
;
}
//根据地址,状态查询用户自己的挂单信息
message
QueryOrderList
{
...
...
@@ -137,8 +128,8 @@ message QueryOrderList {
int32
status
=
1
;
//用户地址信息,必填
string
address
=
2
;
//
索引值
int64
index
=
3
;
//
主键索引
string
primaryKey
=
3
;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32
count
=
4
;
// 0降序,1升序,默认降序
...
...
@@ -147,6 +138,7 @@ message QueryOrderList {
//订单列表
message
OrderList
{
repeated
Order
list
=
1
;
string
primaryKey
=
2
;
}
...
...
plugin/dapp/exchange/types/exchange.go
View file @
ef3012f1
...
...
@@ -2,6 +2,7 @@ package types
import
(
"github.com/33cn/chain33/types"
"reflect"
)
/*
...
...
@@ -73,7 +74,9 @@ var (
}
//定义log的id和具体log类型及名称,填入具体自定义log类型
logMap
=
map
[
int64
]
*
types
.
LogInfo
{
//LogID: {Ty: reflect.TypeOf(LogStruct), Name: LogName},
TyLimitOrderLog
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptExchange
{}),
Name
:
"TyLimitOrderLog"
},
TyMarketOrderLog
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptExchange
{}),
Name
:
"TyMarketOrderLog"
},
TyRevokeOrderLog
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptExchange
{}),
Name
:
"TyRevokeOrderLog"
},
}
//tlog = log.New("module", "exchange.types")
)
...
...
plugin/dapp/exchange/types/exchange.pb.go
View file @
ef3012f1
...
...
@@ -15,8 +15,6 @@ It has these top-level messages:
RevokeOrder
Asset
Order
OrderPrice
OrderID
QueryMarketDepth
MarketDepth
MarketDepthList
...
...
@@ -28,15 +26,12 @@ It has these top-level messages:
*/
package
types
import
(
fmt
"fmt"
proto
"github.com/golang/protobuf/proto"
math
"math"
import
proto
"github.com/golang/protobuf/proto"
import
fmt
"fmt"
import
math
"math"
import
(
context
"golang.org/x/net/context"
grpc
"google.golang.org/grpc"
)
...
...
@@ -321,7 +316,7 @@ func (m *MarketOrder) GetOp() int32 {
// 撤回订单
type
RevokeOrder
struct
{
// 订单号
OrderID
string
`protobuf:"bytes
,1,opt,name=orderID" json:"orderID,omitempty"`
OrderID
int64
`protobuf:"varint
,1,opt,name=orderID" json:"orderID,omitempty"`
}
func
(
m
*
RevokeOrder
)
Reset
()
{
*
m
=
RevokeOrder
{}
}
...
...
@@ -329,11 +324,11 @@ func (m *RevokeOrder) String() string { return proto.CompactTextStrin
func
(
*
RevokeOrder
)
ProtoMessage
()
{}
func
(
*
RevokeOrder
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
4
}
}
func
(
m
*
RevokeOrder
)
GetOrderID
()
string
{
func
(
m
*
RevokeOrder
)
GetOrderID
()
int64
{
if
m
!=
nil
{
return
m
.
OrderID
}
return
""
return
0
}
// 资产类型
...
...
@@ -363,7 +358,7 @@ func (m *Asset) GetSymbol() string {
// 订单信息
type
Order
struct
{
OrderID
string
`protobuf:"bytes
,1,opt,name=orderID" json:"orderID,omitempty"`
OrderID
int64
`protobuf:"varint
,1,opt,name=orderID" json:"orderID,omitempty"`
// Types that are valid to be assigned to Value:
// *Order_LimitOrder
// *Order_MarketOrder
...
...
@@ -410,11 +405,11 @@ func (m *Order) GetValue() isOrder_Value {
return
nil
}
func
(
m
*
Order
)
GetOrderID
()
string
{
func
(
m
*
Order
)
GetOrderID
()
int64
{
if
m
!=
nil
{
return
m
.
OrderID
}
return
""
return
0
}
func
(
m
*
Order
)
GetLimitOrder
()
*
LimitOrder
{
...
...
@@ -554,56 +549,6 @@ func _Order_OneofSizer(msg proto.Message) (n int) {
return
n
}
// 挂单价
type
OrderPrice
struct
{
Price
float64
`protobuf:"fixed64,1,opt,name=price" json:"price,omitempty"`
Index
int64
`protobuf:"varint,2,opt,name=index" json:"index,omitempty"`
}
func
(
m
*
OrderPrice
)
Reset
()
{
*
m
=
OrderPrice
{}
}
func
(
m
*
OrderPrice
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
OrderPrice
)
ProtoMessage
()
{}
func
(
*
OrderPrice
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
7
}
}
func
(
m
*
OrderPrice
)
GetPrice
()
float64
{
if
m
!=
nil
{
return
m
.
Price
}
return
0
}
func
(
m
*
OrderPrice
)
GetIndex
()
int64
{
if
m
!=
nil
{
return
m
.
Index
}
return
0
}
// 单号
type
OrderID
struct
{
ID
string
`protobuf:"bytes,1,opt,name=ID" json:"ID,omitempty"`
Index
int64
`protobuf:"varint,2,opt,name=index" json:"index,omitempty"`
}
func
(
m
*
OrderID
)
Reset
()
{
*
m
=
OrderID
{}
}
func
(
m
*
OrderID
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
OrderID
)
ProtoMessage
()
{}
func
(
*
OrderID
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
8
}
}
func
(
m
*
OrderID
)
GetID
()
string
{
if
m
!=
nil
{
return
m
.
ID
}
return
""
}
func
(
m
*
OrderID
)
GetIndex
()
int64
{
if
m
!=
nil
{
return
m
.
Index
}
return
0
}
// 查询接口
type
QueryMarketDepth
struct
{
// 资产1
...
...
@@ -613,7 +558,7 @@ type QueryMarketDepth struct {
// 操作, 1为买,2为卖
Op
int32
`protobuf:"varint,3,opt,name=op" json:"op,omitempty"`
// 这里用价格作为索引值
Pri
ce
float64
`protobuf:"fixed64,4,opt,name=price" json:"price
,omitempty"`
Pri
maryKey
string
`protobuf:"bytes,4,opt,name=primaryKey" json:"primaryKey
,omitempty"`
// 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
Count
int32
`protobuf:"varint,5,opt,name=count" json:"count,omitempty"`
}
...
...
@@ -621,7 +566,7 @@ type QueryMarketDepth struct {
func
(
m
*
QueryMarketDepth
)
Reset
()
{
*
m
=
QueryMarketDepth
{}
}
func
(
m
*
QueryMarketDepth
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
QueryMarketDepth
)
ProtoMessage
()
{}
func
(
*
QueryMarketDepth
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
9
}
}
func
(
*
QueryMarketDepth
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
7
}
}
func
(
m
*
QueryMarketDepth
)
GetLeftAsset
()
*
Asset
{
if
m
!=
nil
{
...
...
@@ -644,11 +589,11 @@ func (m *QueryMarketDepth) GetOp() int32 {
return
0
}
func
(
m
*
QueryMarketDepth
)
GetPri
ce
()
float64
{
func
(
m
*
QueryMarketDepth
)
GetPri
maryKey
()
string
{
if
m
!=
nil
{
return
m
.
Pri
ce
return
m
.
Pri
maryKey
}
return
0
return
""
}
func
(
m
*
QueryMarketDepth
)
GetCount
()
int32
{
...
...
@@ -675,7 +620,7 @@ type MarketDepth struct {
func
(
m
*
MarketDepth
)
Reset
()
{
*
m
=
MarketDepth
{}
}
func
(
m
*
MarketDepth
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
MarketDepth
)
ProtoMessage
()
{}
func
(
*
MarketDepth
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
10
}
}
func
(
*
MarketDepth
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
8
}
}
func
(
m
*
MarketDepth
)
GetLeftAsset
()
*
Asset
{
if
m
!=
nil
{
...
...
@@ -714,13 +659,14 @@ func (m *MarketDepth) GetOp() int32 {
// 查询接口返回的市场深度列表
type
MarketDepthList
struct
{
List
[]
*
MarketDepth
`protobuf:"bytes,1,rep,name=list" json:"list,omitempty"`
List
[]
*
MarketDepth
`protobuf:"bytes,1,rep,name=list" json:"list,omitempty"`
PrimaryKey
string
`protobuf:"bytes,2,opt,name=primaryKey" json:"primaryKey,omitempty"`
}
func
(
m
*
MarketDepthList
)
Reset
()
{
*
m
=
MarketDepthList
{}
}
func
(
m
*
MarketDepthList
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
MarketDepthList
)
ProtoMessage
()
{}
func
(
*
MarketDepthList
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
11
}
}
func
(
*
MarketDepthList
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
9
}
}
func
(
m
*
MarketDepthList
)
GetList
()
[]
*
MarketDepth
{
if
m
!=
nil
{
...
...
@@ -729,6 +675,13 @@ func (m *MarketDepthList) GetList() []*MarketDepth {
return
nil
}
func
(
m
*
MarketDepthList
)
GetPrimaryKey
()
string
{
if
m
!=
nil
{
return
m
.
PrimaryKey
}
return
""
}
// 查询最新得成交信息,外部接口
type
QueryCompletedOrderList
struct
{
// 资产1
...
...
@@ -736,7 +689,7 @@ type QueryCompletedOrderList struct {
// 资产2
RightAsset
*
Asset
`protobuf:"bytes,2,opt,name=rightAsset" json:"rightAsset,omitempty"`
// 索引值
Index
int64
`protobuf:"varint,3,opt,name=index" json:"index
,omitempty"`
PrimaryKey
string
`protobuf:"bytes,3,opt,name=primaryKey" json:"primaryKey
,omitempty"`
// 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
Count
int32
`protobuf:"varint,4,opt,name=count" json:"count,omitempty"`
// 0降序,1升序,默认降序
...
...
@@ -746,7 +699,7 @@ type QueryCompletedOrderList struct {
func
(
m
*
QueryCompletedOrderList
)
Reset
()
{
*
m
=
QueryCompletedOrderList
{}
}
func
(
m
*
QueryCompletedOrderList
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
QueryCompletedOrderList
)
ProtoMessage
()
{}
func
(
*
QueryCompletedOrderList
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
2
}
}
func
(
*
QueryCompletedOrderList
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
0
}
}
func
(
m
*
QueryCompletedOrderList
)
GetLeftAsset
()
*
Asset
{
if
m
!=
nil
{
...
...
@@ -762,11 +715,11 @@ func (m *QueryCompletedOrderList) GetRightAsset() *Asset {
return
nil
}
func
(
m
*
QueryCompletedOrderList
)
Get
Index
()
int64
{
func
(
m
*
QueryCompletedOrderList
)
Get
PrimaryKey
()
string
{
if
m
!=
nil
{
return
m
.
Index
return
m
.
PrimaryKey
}
return
0
return
""
}
func
(
m
*
QueryCompletedOrderList
)
GetCount
()
int32
{
...
...
@@ -785,19 +738,19 @@ func (m *QueryCompletedOrderList) GetDirection() int32 {
// 根据orderID去查询订单信息
type
QueryOrder
struct
{
OrderID
string
`protobuf:"bytes
,1,opt,name=orderID" json:"orderID,omitempty"`
OrderID
int64
`protobuf:"varint
,1,opt,name=orderID" json:"orderID,omitempty"`
}
func
(
m
*
QueryOrder
)
Reset
()
{
*
m
=
QueryOrder
{}
}
func
(
m
*
QueryOrder
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
QueryOrder
)
ProtoMessage
()
{}
func
(
*
QueryOrder
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
3
}
}
func
(
*
QueryOrder
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
1
}
}
func
(
m
*
QueryOrder
)
GetOrderID
()
string
{
func
(
m
*
QueryOrder
)
GetOrderID
()
int64
{
if
m
!=
nil
{
return
m
.
OrderID
}
return
""
return
0
}
// 根据地址,状态查询用户自己的挂单信息
...
...
@@ -806,8 +759,8 @@ type QueryOrderList struct {
Status
int32
`protobuf:"varint,1,opt,name=status" json:"status,omitempty"`
// 用户地址信息,必填
Address
string
`protobuf:"bytes,2,opt,name=address" json:"address,omitempty"`
//
索引值
Index
int64
`protobuf:"varint,3,opt,name=index" json:"index
,omitempty"`
//
主键索引
PrimaryKey
string
`protobuf:"bytes,3,opt,name=primaryKey" json:"primaryKey
,omitempty"`
// 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
Count
int32
`protobuf:"varint,4,opt,name=count" json:"count,omitempty"`
// 0降序,1升序,默认降序
...
...
@@ -817,7 +770,7 @@ type QueryOrderList struct {
func
(
m
*
QueryOrderList
)
Reset
()
{
*
m
=
QueryOrderList
{}
}
func
(
m
*
QueryOrderList
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
QueryOrderList
)
ProtoMessage
()
{}
func
(
*
QueryOrderList
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
4
}
}
func
(
*
QueryOrderList
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
2
}
}
func
(
m
*
QueryOrderList
)
GetStatus
()
int32
{
if
m
!=
nil
{
...
...
@@ -833,11 +786,11 @@ func (m *QueryOrderList) GetAddress() string {
return
""
}
func
(
m
*
QueryOrderList
)
Get
Index
()
int64
{
func
(
m
*
QueryOrderList
)
Get
PrimaryKey
()
string
{
if
m
!=
nil
{
return
m
.
Index
return
m
.
PrimaryKey
}
return
0
return
""
}
func
(
m
*
QueryOrderList
)
GetCount
()
int32
{
...
...
@@ -856,13 +809,14 @@ func (m *QueryOrderList) GetDirection() int32 {
// 订单列表
type
OrderList
struct
{
List
[]
*
Order
`protobuf:"bytes,1,rep,name=list" json:"list,omitempty"`
List
[]
*
Order
`protobuf:"bytes,1,rep,name=list" json:"list,omitempty"`
PrimaryKey
string
`protobuf:"bytes,2,opt,name=primaryKey" json:"primaryKey,omitempty"`
}
func
(
m
*
OrderList
)
Reset
()
{
*
m
=
OrderList
{}
}
func
(
m
*
OrderList
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
OrderList
)
ProtoMessage
()
{}
func
(
*
OrderList
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
5
}
}
func
(
*
OrderList
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
3
}
}
func
(
m
*
OrderList
)
GetList
()
[]
*
Order
{
if
m
!=
nil
{
...
...
@@ -871,6 +825,13 @@ func (m *OrderList) GetList() []*Order {
return
nil
}
func
(
m
*
OrderList
)
GetPrimaryKey
()
string
{
if
m
!=
nil
{
return
m
.
PrimaryKey
}
return
""
}
// exchange执行票据日志
type
ReceiptExchange
struct
{
Order
*
Order
`protobuf:"bytes,1,opt,name=order" json:"order,omitempty"`
...
...
@@ -881,7 +842,7 @@ type ReceiptExchange struct {
func
(
m
*
ReceiptExchange
)
Reset
()
{
*
m
=
ReceiptExchange
{}
}
func
(
m
*
ReceiptExchange
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptExchange
)
ProtoMessage
()
{}
func
(
*
ReceiptExchange
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
6
}
}
func
(
*
ReceiptExchange
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
4
}
}
func
(
m
*
ReceiptExchange
)
GetOrder
()
*
Order
{
if
m
!=
nil
{
...
...
@@ -912,8 +873,6 @@ func init() {
proto
.
RegisterType
((
*
RevokeOrder
)(
nil
),
"types.RevokeOrder"
)
proto
.
RegisterType
((
*
Asset
)(
nil
),
"types.asset"
)
proto
.
RegisterType
((
*
Order
)(
nil
),
"types.Order"
)
proto
.
RegisterType
((
*
OrderPrice
)(
nil
),
"types.OrderPrice"
)
proto
.
RegisterType
((
*
OrderID
)(
nil
),
"types.OrderID"
)
proto
.
RegisterType
((
*
QueryMarketDepth
)(
nil
),
"types.QueryMarketDepth"
)
proto
.
RegisterType
((
*
MarketDepth
)(
nil
),
"types.MarketDepth"
)
proto
.
RegisterType
((
*
MarketDepthList
)(
nil
),
"types.MarketDepthList"
)
...
...
@@ -965,47 +924,46 @@ var _Exchange_serviceDesc = grpc.ServiceDesc{
func
init
()
{
proto
.
RegisterFile
(
"exchange.proto"
,
fileDescriptor0
)
}
var
fileDescriptor0
=
[]
byte
{
// 659 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xb4
,
0x55
,
0xed
,
0x6a
,
0xd4
,
0x4c
,
0x14
,
0xee
,
0xe4
,
0xa3
,
0xdb
,
0x9c
,
0x7d
,
0xd9
,
0xbe
,
0x0e
,
0xa2
,
0x41
,
0x44
,
0x96
,
0xfc
,
0xa8
,
0x45
,
0x74
,
0x85
,
0x16
,
0xfc
,
0xf8
,
0x59
,
0xad
,
0xd0
,
0x42
,
0xa5
,
0x3a
,
0x78
,
0x03
,
0x69
,
0x72
,
0xec
,
0x86
,
0x66
,
0x37
,
0x21
,
0x99
,
0x2d
,
0x5d
,
0xbc
,
0x05
,
0xc1
,
0x9b
,
0x50
,
0xf0
,
0x26
,
0xc4
,
0x3b
,
0xf0
,
0x9a
,
0x64
,
0x4e
,
0x26
,
0x99
,
0xd9
,
0x76
,
0xa5
,
0xa2
,
0xee
,
0xbf
,
0x3c
,
0x73
,
0x3e
,
0xf2
,
0x9c
,
0x73
,
0x9e
,
0x33
,
0x03
,
0x03
,
0xbc
,
0x48
,
0xc6
,
0xf1
,
0xf4
,
0x14
,
0x47
,
0x65
,
0x55
,
0xc8
,
0x82
,
0xfb
,
0x72
,
0x5e
,
0x62
,
0x1d
,
0x01
,
0x6c
,
0xbc
,
0xd2
,
0x86
,
0xe8
,
0x07
,
0x83
,
0x41
,
0x0b
,
0xf6
,
0x12
,
0x99
,
0x15
,
0x53
,
0xbe
,
0x0b
,
0x90
,
0x67
,
0x93
,
0x4c
,
0x1e
,
0x57
,
0x29
,
0x56
,
0x21
,
0x1b
,
0xb2
,
0xed
,
0xfe
,
0xce
,
0x8d
,
0x11
,
0x85
,
0x8e
,
0x8e
,
0x3a
,
0xc3
,
0xc1
,
0x9a
,
0xb0
,
0xdc
,
0xf8
,
0x13
,
0xe8
,
0x4f
,
0xe2
,
0xea
,
0x0c
,
0x75
,
0x94
,
0x43
,
0x51
,
0x5c
,
0x47
,
0xbd
,
0x36
,
0x96
,
0x83
,
0x35
,
0x61
,
0x3b
,
0xaa
,
0xb8
,
0x0a
,
0xcf
,
0x8b
,
0x33
,
0x6c
,
0xe2
,
0xdc
,
0x85
,
0x38
,
0x61
,
0x2c
,
0x2a
,
0xce
,
0x72
,
0xe4
,
0x03
,
0x70
,
0xe4
,
0x3c
,
0x5c
,
0x1f
,
0xb2
,
0x6d
,
0x5f
,
0x38
,
0x72
,
0xfe
,
0xa2
,
0x07
,
0xfe
,
0x79
,
0x9c
,
0xcf
,
0x30
,
0xfa
,
0xcc
,
0x00
,
0x0c
,
0x4b
,
0xfe
,
0x00
,
0x82
,
0x1c
,
0xdf
,
0xcb
,
0xbd
,
0xba
,
0x46
,
0xa9
,
0x6b
,
0xf9
,
0x4f
,
0x67
,
0x8f
,
0xd5
,
0x99
,
0x30
,
0x66
,
0xfe
,
0x10
,
0xa0
,
0xca
,
0x4e
,
0xc7
,
0xda
,
0xd9
,
0x59
,
0xe2
,
0x6c
,
0xd9
,
0xf9
,
0x4d
,
0xf0
,
0xcb
,
0x2a
,
0x4b
,
0x90
,
0x38
,
0x33
,
0xd1
,
0x00
,
0x7e
,
0x0b
,
0xd6
,
0xe3
,
0x49
,
0x31
,
0x9b
,
0xca
,
0xd0
,
0x1b
,
0xb2
,
0x6d
,
0x57
,
0x68
,
0xa4
,
0xf8
,
0x16
,
0x65
,
0xe8
,
0x37
,
0x7c
,
0x8b
,
0x32
,
0xfa
,
0xc4
,
0xa0
,
0x6f
,
0xb5
,
0x65
,
0x85
,
0x3c
,
0x0d
,
0x23
,
0x77
,
0x09
,
0x23
,
0xaf
,
0x63
,
0x74
,
0x1f
,
0xfa
,
0x56
,
0xbf
,
0x79
,
0x08
,
0xbd
,
0x42
,
0x7d
,
0x1c
,
0xee
,
0x13
,
0x9d
,
0x40
,
0xb4
,
0x30
,
0x7a
,
0x0a
,
0x7e
,
0xdc
,
0x66
,
0xc6
,
0x0b
,
0x4c
,
0xb4
,
0x48
,
0x02
,
0xa1
,
0x91
,
0x3a
,
0xaf
,
0xe7
,
0x93
,
0x93
,
0x22
,
0x27
,
0x6e
,
0x81
,
0xd0
,
0x28
,
0xfa
,
0xee
,
0x80
,
0x7f
,
0x4d
,
0xf2
,
0x4b
,
0xe2
,
0x73
,
0xfe
,
0x48
,
0x7c
,
0xee
,
0xef
,
0x8a
,
0xaf
,
0x11
,
0x91
,
0xd7
,
0x8a
,
0x88
,
0xdf
,
0x81
,
0x0d
,
0x55
,
0xc2
,
0x4c
,
0x62
,
0x4a
,
0xa3
,
0x72
,
0x45
,
0x87
,
0x15
,
0xe5
,
0x93
,
0x38
,
0x8f
,
0xa7
,
0x09
,
0x92
,
0xea
,
0x5c
,
0xd1
,
0x42
,
0x2a
,
0x57
,
0xc6
,
0x72
,
0x56
,
0x87
,
0x3d
,
0xca
,
0xa4
,
0x11
,
0xe7
,
0xe0
,
0xc5
,
0x69
,
0x5a
,
0x85
,
0x1b
,
0x54
,
0x21
,
0x7d
,
0xf3
,
0x7b
,
0x00
,
0xb3
,
0x32
,
0x8d
,
0x25
,
0xbe
,
0xcb
,
0x26
,
0x18
,
0x06
,
0x94
,
0xc8
,
0x3a
,
0x51
,
0xa2
,
0xca
,
0xa6
,
0x29
,
0x5e
,
0x84
,
0x40
,
0xa6
,
0x06
,
0x18
,
0x71
,
0x3f
,
0x03
,
0x20
,
0xe6
,
0x6f
,
0x48
,
0x6b
,
0x9d
,
0x02
,
0x99
,
0xad
,
0xc0
,
0x2e
,
0x85
,
0x63
,
0xa5
,
0x88
,
0x1e
,
0x43
,
0xef
,
0x58
,
0xb7
,
0x78
,
0x00
,
0x4e
,
0xd7
,
0x77
,
0xe7
,
0x70
,
0xff
,
0x17
,
0x01
,
0x5f
,
0x19
,
0xfc
,
0xff
,
0x76
,
0x86
,
0xd5
,
0xbc
,
0xe9
,
0xdf
,
0x3e
,
0x96
,
0x72
,
0xbc
,
0x42
,
0x95
,
0x36
,
0x6a
,
0x74
,
0x5b
,
0x35
,
0x9a
,
0xda
,
0xbc
,
0x4b
,
0xb5
,
0x25
,
0x24
,
0xe5
,
0x66
,
0x91
,
0x1a
,
0x10
,
0x7d
,
0xe9
,
0x76
,
0x69
,
0xd5
,
0x2c
,
0xff
,
0x6e
,
0xe7
,
0x9f
,
0xc3
,
0xa6
,
0x45
,
0xf3
,
0x28
,
0xab
,
0x25
,
0xdf
,
0x02
,
0x2f
,
0xcf
,
0x6a
,
0xc5
,
0xd2
,
0xbd
,
0x22
,
0x59
,
0xf2
,
0x12
,
0x64
,
0x8f
,
0xbe
,
0x31
,
0xb8
,
0x4d
,
0xd3
,
0x78
,
0x59
,
0x4c
,
0xca
,
0x1c
,
0x25
,
0xa6
,
0x34
,
0x4d
,
0xca
,
0xb1
,
0xd2
,
0x72
,
0x1b
,
0x65
,
0xb8
,
0x96
,
0x32
,
0xcc
,
0x10
,
0x3c
,
0x6b
,
0x08
,
0xfc
,
0x2e
,
0x04
,
0x69
,
0x56
,
0x21
,
0x3d
,
0x21
,
0xba
,
0x66
,
0x73
,
0x10
,
0x6d
,
0x01
,
0x10
,
0xfd
,
0xeb
,
0xee
,
0x96
,
0x8f
,
0x0c
,
0x06
,
0xc6
,
0x91
,
0xca
,
0x33
,
0xeb
,
0xc5
,
0x16
,
0xd6
,
0x2b
,
0x84
,
0x9e
,
0x5a
,
0x29
,
0xac
,
0x6b
,
0x7d
,
0xcd
,
0xb4
,
0xf0
,
0x1f
,
0xd2
,
0x7e
,
0x04
,
0x81
,
0x21
,
0x32
,
0x5c
,
0x98
,
0x55
,
0xdb
,
0x35
,
0xb2
,
0xeb
,
0x29
,
0x7d
,
0x80
,
0x4d
,
0x81
,
0x09
,
0x66
,
0xa5
,
0x6c
,
0x9f
,
0x54
,
0x1e
,
0x81
,
0x5f
,
0x58
,
0xef
,
0xe8
,
0x62
,
0x54
,
0x63
,
0xe2
,
0x23
,
0x75
,
0x7d
,
0xc9
,
0x64
,
0x4c
,
0x87
,
0xaa
,
0x9a
,
0xab
,
0xf9
,
0x6d
,
0x87
,
0xe5
,
0xf5
,
0xed
,
0x80
,
0xba
,
0xbc
,
0x9a
,
0xbf
,
0x9e
,
0xac
,
0xd3
,
0x7b
,
0xbf
,
0xfb
,
0x33
,
0x00
,
0x00
,
0xff
,
0xff
,
0xd8
,
0xc6
,
0x87
,
0x60
,
0x01
,
0x08
,
0x00
,
0x00
,
// 647 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xb4
,
0x55
,
0xcf
,
0x6e
,
0xd3
,
0x4e
,
0x10
,
0xae
,
0xed
,
0xb8
,
0xa9
,
0x27
,
0x3f
,
0xa5
,
0x3f
,
0x56
,
0x08
,
0x2c
,
0x84
,
0x50
,
0xe4
,
0x43
,
0xa9
,
0x10
,
0xca
,
0xa1
,
0x95
,
0xe0
,
0x5c
,
0x28
,
0x52
,
0x11
,
0xad
,
0x10
,
0x2b
,
0x2e
,
0x1c
,
0x5d
,
0x7b
,
0x68
,
0x56
,
0xb5
,
0x63
,
0x6b
,
0xbd
,
0xa9
,
0x1a
,
0xf1
,
0x10
,
0xdc
,
0x78
,
0x02
,
0x78
,
0x01
,
0x5e
,
0x80
,
0x23
,
0x37
,
0x9e
,
0x09
,
0xed
,
0xec
,
0x3a
,
0xde
,
0xa4
,
0x45
,
0xad
,
0x40
,
0xb9
,
0xf9
,
0x9b
,
0x7f
,
0xfe
,
0x66
,
0xe6
,
0xdb
,
0x5d
,
0x18
,
0xe2
,
0x65
,
0x36
,
0x49
,
0xa7
,
0x67
,
0x38
,
0xae
,
0x65
,
0xa5
,
0x2a
,
0x16
,
0xaa
,
0x79
,
0x8d
,
0x4d
,
0x02
,
0xb0
,
0xf5
,
0xca
,
0x3a
,
0x92
,
0x5f
,
0x1e
,
0x0c
,
0x5b
,
0x70
,
0x90
,
0x29
,
0x51
,
0x4d
,
0xd9
,
0x3e
,
0x40
,
0x21
,
0x4a
,
0xa1
,
0xde
,
0xca
,
0x1c
,
0x65
,
0xec
,
0x8d
,
0xbc
,
0xdd
,
0xc1
,
0xde
,
0x9d
,
0x31
,
0xa5
,
0x8e
,
0x8f
,
0x17
,
0x8e
,
0xa3
,
0x0d
,
0xee
,
0x84
,
0xb1
,
0x67
,
0x30
,
0x28
,
0x53
,
0x79
,
0x8e
,
0x36
,
0xcb
,
0xa7
,
0x2c
,
0x66
,
0xb3
,
0x4e
,
0x3a
,
0xcf
,
0xd1
,
0x06
,
0x77
,
0x03
,
0x75
,
0x9e
,
0xc4
,
0x8b
,
0xea
,
0x1c
,
0x4d
,
0x5e
,
0xb0
,
0x94
,
0xc7
,
0x3b
,
0x8f
,
0xce
,
0x73
,
0x02
,
0xd9
,
0x10
,
0x7c
,
0x35
,
0x8f
,
0x37
,
0x47
,
0xde
,
0x6e
,
0xc8
,
0x7d
,
0x35
,
0x7f
,
0xd1
,
0x87
,
0xf0
,
0x22
,
0x2d
,
0x66
,
0x98
,
0x7c
,
0xf5
,
0x00
,
0x3a
,
0x96
,
0xec
,
0x09
,
0x44
,
0x05
,
0x7e
,
0x54
,
0x07
,
0x4d
,
0x83
,
0xca
,
0xf6
,
0xf2
,
0x9f
,
0xad
,
0x9e
,
0x6a
,
0x1b
,
0xef
,
0xdc
,
0xec
,
0x29
,
0x80
,
0x14
,
0x67
,
0x13
,
0x1b
,
0xec
,
0x5f
,
0x13
,
0xec
,
0xf8
,
0xd9
,
0x5d
,
0x08
,
0x6b
,
0x29
,
0x32
,
0x24
,
0xce
,
0x1e
,
0x37
,
0x80
,
0xdd
,
0x83
,
0xcd
,
0xb4
,
0xac
,
0x66
,
0x53
,
0x15
,
0xf7
,
0x46
,
0xde
,
0x6e
,
0xc0
,
0x2d
,
0xd2
,
0x7c
,
0xab
,
0x3a
,
0x0e
,
0x0d
,
0xdf
,
0xaa
,
0x4e
,
0x3e
,
0x7b
,
0x30
,
0x70
,
0xc6
,
0xb2
,
0x46
,
0x9e
,
0x1d
,
0xa3
,
0xe0
,
0x1a
,
0x46
,
0xbd
,
0x05
,
0xa3
,
0xc7
,
0x30
,
0x70
,
0xe6
,
0xcd
,
0x62
,
0xe8
,
0x57
,
0xfa
,
0xe3
,
0xf5
,
0x21
,
0xd1
,
0x09
,
0x78
,
0x0b
,
0x93
,
0xe7
,
0x10
,
0xa6
,
0x6d
,
0x65
,
0xbc
,
0xc4
,
0xcc
,
0x8a
,
0x24
,
0xe2
,
0x16
,
0x69
,
0x7b
,
0x33
,
0x2f
,
0x4f
,
0xab
,
0x82
,
0xb8
,
0x45
,
0xdc
,
0xa2
,
0xe4
,
0x87
,
0x0f
,
0xe1
,
0x0d
,
0xc5
,
0x57
,
0xc4
,
0xe7
,
0xff
,
0x95
,
0xf8
,
0x82
,
0xdb
,
0x8a
,
0xcf
,
0x88
,
0xa8
,
0xd7
,
0x8a
,
0x88
,
0x3d
,
0x80
,
0x2d
,
0xdd
,
0xc2
,
0x4c
,
0x61
,
0x4e
,
0xab
,
0x0a
,
0xf8
,
0x02
,
0x6b
,
0xca
,
0xa7
,
0x69
,
0x91
,
0x4e
,
0x33
,
0x24
,
0xd5
,
0x05
,
0xbc
,
0x85
,
0xd4
,
0xae
,
0x4a
,
0xd5
,
0xac
,
0x89
,
0xfb
,
0x54
,
0xc9
,
0x22
,
0xc6
,
0xa0
,
0x97
,
0xe6
,
0xb9
,
0x8c
,
0xb7
,
0x68
,
0x08
,
0xf4
,
0xcd
,
0x1e
,
0x01
,
0xcc
,
0xea
,
0x3c
,
0x55
,
0xf8
,
0x5e
,
0x94
,
0x18
,
0x47
,
0x54
,
0xc8
,
0xb1
,
0x68
,
0x51
,
0x89
,
0x69
,
0x8e
,
0x97
,
0x31
,
0x90
,
0xcb
,
0x80
,
0x4e
,
0xdc
,
0xdf
,
0x3d
,
0xf8
,
0xff
,
0xdd
,
0x0c
,
0xe5
,
0xdc
,
0x34
,
0x75
,
0x88
,
0xb5
,
0x9a
,
0xac
,
0x51
,
0x3a
,
0x46
,
0x22
,
0x41
,
0x2b
,
0x11
,
0xcd
,
0xbe
,
0x96
,
0xa2
,
0x4c
,
0xe5
,
0xfc
,
0x0d
,
0x9a
,
0xb9
,
0x45
,
0xdc
,
0xb1
,
0x68
,
0xf6
,
0x19
,
0x29
,
0xcd
,
0xe8
,
0xdc
,
0x80
,
0xe4
,
0xdb
,
0x42
,
0xea
,
0xeb
,
0xe6
,
0xfb
,
0x6f
,
0x47
,
0xf2
,
0x03
,
0x6c
,
0x3b
,
0x34
,
0x8f
,
0x45
,
0xa3
,
0xd8
,
0x0e
,
0xf4
,
0x0a
,
0xd1
,
0x68
,
0x96
,
0xc1
,
0x15
,
0x45
,
0x51
,
0x14
,
0x27
,
0xff
,
0xca
,
0x60
,
0xfc
,
0xd5
,
0xc1
,
0x24
,
0x3f
,
0x3d
,
0xb8
,
0x4f
,
0x7b
,
0x7b
,
0x59
,
0x95
,
0x75
,
0x81
,
0x0a
,
0x73
,
0x12
,
0x20
,
0xfd
,
0x63
,
0x7d
,
0xe3
,
0x58
,
0x66
,
0x15
,
0xfc
,
0x79
,
0x5d
,
0x3d
,
0x67
,
0x5d
,
0xec
,
0x21
,
0x44
,
0xb9
,
0x90
,
0x48
,
0x6f
,
0x81
,
0x9d
,
0x4e
,
0x67
,
0x48
,
0x76
,
0x00
,
0xa8
,
0x91
,
0x9b
,
0x2e
,
0x89
,
0x2f
,
0x1e
,
0x0c
,
0xbb
,
0x40
,
0x6a
,
0xb4
,
0x3b
,
0x27
,
0xde
,
0xd2
,
0x39
,
0x89
,
0xa1
,
0xaf
,
0xcf
,
0x06
,
0x36
,
0x8d
,
0x9d
,
0x5c
,
0x0b
,
0xd7
,
0xd2
,
0xc0
,
0x09
,
0x44
,
0x1d
,
0xa5
,
0xd1
,
0xd2
,
0x7e
,
0xdb
,
0x49
,
0x92
,
0xff
,
0x96
,
0x9b
,
0xfd
,
0x04
,
0xdb
,
0x1c
,
0x33
,
0x14
,
0xb5
,
0x6a
,
0x5f
,
0x51
,
0x96
,
0x40
,
0x58
,
0x39
,
0x4f
,
0xe7
,
0x72
,
0x55
,
0xe3
,
0x62
,
0x63
,
0x7d
,
0x63
,
0xa9
,
0x6c
,
0x42
,
0x46
,
0xdd
,
0xf7
,
0xd5
,
0xff
,
0xbb
,
0x01
,
0xdd
,
0xbd
,
0x10
,
0x38
,
0xf7
,
0xc2
,
0x1e
,
0xe8
,
0xfb
,
0xca
,
0xfc
,
0xf5
,
0x74
,
0x93
,
0x9e
,
0xf8
,
0xfd
,
0xdf
,
0x01
,
0x00
,
0x00
,
0xff
,
0xff
,
0xf3
,
0x6d
,
0x05
,
0xfd
,
0xf4
,
0x07
,
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