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
df072618
Commit
df072618
authored
Jan 07, 2020
by
pengjun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
#627 fix debtceiling & liquidation recovery
parent
d4c38318
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
285 additions
and
73 deletions
+285
-73
collateralize_test.go
plugin/dapp/collateralize/executor/collateralize_test.go
+84
-9
collateralizedb.go
plugin/dapp/collateralize/executor/collateralizedb.go
+39
-16
exec_local.go
plugin/dapp/collateralize/executor/exec_local.go
+20
-12
exec_local.go
plugin/dapp/issuance/executor/exec_local.go
+20
-12
issuance_test.go
plugin/dapp/issuance/executor/issuance_test.go
+82
-9
issuancedb.go
plugin/dapp/issuance/executor/issuancedb.go
+40
-15
No files found.
plugin/dapp/collateralize/executor/collateralize_test.go
View file @
df072618
...
...
@@ -449,7 +449,7 @@ func TestCollateralize(t *testing.T) {
}
p8
:=
&
pkt
.
CollateralizeFeedTx
{}
p8
.
Price
=
append
(
p8
.
Price
,
0.2
5
)
p8
.
Price
=
append
(
p8
.
Price
,
0.2
8
)
p8
.
Volume
=
append
(
p8
.
Volume
,
100
)
createTx
,
err
=
pkt
.
CreateRawCollateralizeFeedTx
(
env
.
cfg
,
p8
)
if
err
!=
nil
{
...
...
@@ -478,16 +478,91 @@ func TestCollateralize(t *testing.T) {
}
// query collateralize by status
res
,
err
=
exec
.
Query
(
"CollateralizeRecordByStatus"
,
types
.
Encode
(
&
pkt
.
ReqCollateralizeRecordByStatus
{
CollateralizeId
:
common
.
ToHex
(
collateralizeID
),
Status
:
2
}))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
res
)
res
,
err
=
exec
.
Query
(
"CollateralizeRecordByStatus"
,
types
.
Encode
(
&
pkt
.
ReqCollateralizeRecordByStatus
{
CollateralizeId
:
common
.
ToHex
(
collateralizeID
),
Status
:
4
}))
assert
.
Nil
(
t
,
res
)
p81
:=
&
pkt
.
CollateralizeFeedTx
{}
p81
.
Price
=
append
(
p81
.
Price
,
0.5
)
p81
.
Volume
=
append
(
p81
.
Volume
,
100
)
createTx
,
err
=
pkt
.
CreateRawCollateralizeFeedTx
(
env
.
cfg
,
p81
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
createTx
.
Execer
=
[]
byte
(
pkt
.
CollateralizeX
)
createTx
,
err
=
signTx
(
createTx
,
PrivKeyB
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process sign"
,
"err"
,
err
)
}
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
1
,
env
.
difficulty
)
receipt
,
err
=
exec
.
Exec
(
createTx
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
receipt
)
t
.
Log
(
receipt
)
for
_
,
kv
:=
range
receipt
.
KV
{
env
.
db
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptData
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
createTx
,
receiptData
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
set
)
for
_
,
kv
:=
range
set
.
KV
{
env
.
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
// query collateralize by status
res
,
err
=
exec
.
Query
(
"CollateralizeRecordByStatus"
,
types
.
Encode
(
&
pkt
.
ReqCollateralizeRecordByStatus
{
CollateralizeId
:
common
.
ToHex
(
collateralizeID
),
Status
:
4
}))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
res
)
p9
:=
&
pkt
.
CollateralizeFeedTx
{}
p9
.
Price
=
append
(
p9
.
Price
,
0.25
)
p9
.
Volume
=
append
(
p9
.
Volume
,
100
)
createTx
,
err
=
pkt
.
CreateRawCollateralizeFeedTx
(
env
.
cfg
,
p9
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
createTx
.
Execer
=
[]
byte
(
pkt
.
CollateralizeX
)
createTx
,
err
=
signTx
(
createTx
,
PrivKeyB
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process sign"
,
"err"
,
err
)
}
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
1
,
env
.
difficulty
)
receipt
,
err
=
exec
.
Exec
(
createTx
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
receipt
)
t
.
Log
(
receipt
)
for
_
,
kv
:=
range
receipt
.
KV
{
env
.
db
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptData
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
createTx
,
receiptData
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
set
)
for
_
,
kv
:=
range
set
.
KV
{
env
.
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
// query collateralize by status
res
,
err
=
exec
.
Query
(
"CollateralizeRecordByStatus"
,
types
.
Encode
(
&
pkt
.
ReqCollateralizeRecordByStatus
{
CollateralizeId
:
common
.
ToHex
(
collateralizeID
),
Status
:
3
}))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
res
)
res
,
err
=
exec
.
Query
(
"CollateralizeRecordByStatus"
,
types
.
Encode
(
&
pkt
.
ReqCollateralizeRecordByStatus
{
CollateralizeId
:
common
.
ToHex
(
collateralizeID
),
Status
:
4
}))
assert
.
Nil
(
t
,
res
)
// expire liquidate
p
9
:=
&
pkt
.
CollateralizeBorrowTx
{
p
10
:=
&
pkt
.
CollateralizeBorrowTx
{
CollateralizeID
:
common
.
ToHex
(
collateralizeID
),
Value
:
100
,
}
createTx
,
err
=
pkt
.
CreateRawCollateralizeBorrowTx
(
env
.
cfg
,
p
9
)
createTx
,
err
=
pkt
.
CreateRawCollateralizeBorrowTx
(
env
.
cfg
,
p
10
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
...
...
@@ -513,10 +588,10 @@ func TestCollateralize(t *testing.T) {
env
.
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
p1
0
:=
&
pkt
.
CollateralizeFeedTx
{}
p1
0
.
Price
=
append
(
p10
.
Price
,
1
)
p1
0
.
Volume
=
append
(
p10
.
Volume
,
100
)
createTx
,
err
=
pkt
.
CreateRawCollateralizeFeedTx
(
env
.
cfg
,
p1
0
)
p1
1
:=
&
pkt
.
CollateralizeFeedTx
{}
p1
1
.
Price
=
append
(
p11
.
Price
,
1
)
p1
1
.
Volume
=
append
(
p11
.
Volume
,
100
)
createTx
,
err
=
pkt
.
CreateRawCollateralizeFeedTx
(
env
.
cfg
,
p1
1
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
...
...
@@ -548,11 +623,11 @@ func TestCollateralize(t *testing.T) {
assert
.
NotNil
(
t
,
res
)
// collateralize retrieve
p1
1
:=
&
pkt
.
CollateralizeRetrieveTx
{
p1
2
:=
&
pkt
.
CollateralizeRetrieveTx
{
CollateralizeID
:
common
.
ToHex
(
collateralizeID
),
Balance
:
100
,
}
createTx
,
err
=
pkt
.
CreateRawCollateralizeRetrieveTx
(
env
.
cfg
,
p1
1
)
createTx
,
err
=
pkt
.
CreateRawCollateralizeRetrieveTx
(
env
.
cfg
,
p1
2
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
...
...
plugin/dapp/collateralize/executor/collateralizedb.go
View file @
df072618
...
...
@@ -528,7 +528,7 @@ func (action *Action) CollateralizeBorrow(borrow *pty.CollateralizeBorrow) (*typ
// 查找对应的借贷ID
collateralize
,
err
:=
queryCollateralizeByID
(
action
.
db
,
borrow
.
CollateralizeId
)
if
err
!=
nil
{
clog
.
Error
(
"CollateralizeBorrow"
,
"CollateralizeId"
,
borrow
.
CollateralizeId
,
"error"
,
err
)
clog
.
Error
(
"CollateralizeBorrow
.queryCollateralizeByID
"
,
"CollateralizeId"
,
borrow
.
CollateralizeId
,
"error"
,
err
)
return
nil
,
err
}
...
...
@@ -547,8 +547,10 @@ func (action *Action) CollateralizeBorrow(borrow *pty.CollateralizeBorrow) (*typ
}
// 借贷金额不超过个人限额
if
borrow
.
GetValue
()
>
coll
.
DebtCeiling
{
clog
.
Error
(
"CollateralizeBorrow"
,
"CollID"
,
coll
.
CollateralizeId
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"borrow value"
,
borrow
.
GetValue
(),
"error"
,
pty
.
ErrCollateralizeExceedDebtCeiling
)
userBalance
,
_
:=
queryCollateralizeUserBalance
(
action
.
db
,
action
.
localDB
,
action
.
fromaddr
)
if
borrow
.
GetValue
()
+
userBalance
>
coll
.
DebtCeiling
{
clog
.
Error
(
"CollateralizeBorrow"
,
"CollID"
,
coll
.
CollateralizeId
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"borrow value"
,
borrow
.
GetValue
(),
"current balance"
,
userBalance
,
"error"
,
pty
.
ErrCollateralizeExceedDebtCeiling
)
return
nil
,
pty
.
ErrCollateralizeExceedDebtCeiling
}
...
...
@@ -899,13 +901,17 @@ func (action *Action) systemLiquidation(coll *pty.Collateralize, price int64) (*
for
index
,
borrowRecord
:=
range
coll
.
BorrowRecords
{
if
(
borrowRecord
.
LiquidationPrice
*
PriceWarningRate
)
/
1e4
<
price
{
// 价格恢复,告警记录恢复
if
borrowRecord
.
Status
==
pty
.
CollateralizeUserStatusWarning
{
borrowRecord
.
PreStatus
=
borrowRecord
.
Status
borrowRecord
.
Status
=
pty
.
CollateralizeUserStatusCreate
log
:=
action
.
GetFeedReceiptLog
(
coll
,
borrowRecord
)
logs
=
append
(
logs
,
log
)
}
continue
}
// 价格低于清算线,记录清算
if
borrowRecord
.
LiquidationPrice
>=
price
{
getGuarantorAddr
,
err
:=
getGuarantorAddr
(
action
.
db
)
if
err
!=
nil
{
...
...
@@ -931,13 +937,19 @@ func (action *Action) systemLiquidation(coll *pty.Collateralize, price int64) (*
coll
.
InvalidRecords
=
append
(
coll
.
InvalidRecords
,
borrowRecord
)
coll
.
BorrowRecords
=
append
(
coll
.
BorrowRecords
[
:
index
],
coll
.
BorrowRecords
[
index
+
1
:
]
...
)
coll
.
CollBalance
-=
borrowRecord
.
CollateralValue
}
else
{
log
:=
action
.
GetFeedReceiptLog
(
coll
,
borrowRecord
)
logs
=
append
(
logs
,
log
)
continue
}
// 价格高于清算线,且还不处于告警状态,记录告警
if
borrowRecord
.
Status
!=
pty
.
CollateralizeUserStatusWarning
{
borrowRecord
.
PreStatus
=
borrowRecord
.
Status
borrowRecord
.
Status
=
pty
.
CollateralizeUserStatusWarning
log
:=
action
.
GetFeedReceiptLog
(
coll
,
borrowRecord
)
logs
=
append
(
logs
,
log
)
}
log
:=
action
.
GetFeedReceiptLog
(
coll
,
borrowRecord
)
logs
=
append
(
logs
,
log
)
}
// 保存
...
...
@@ -961,6 +973,7 @@ func (action *Action) expireLiquidation(coll *pty.Collateralize) (*types.Receipt
continue
}
// 超过超时时间,记录清算
if
borrowRecord
.
ExpireTime
<=
action
.
blocktime
{
getGuarantorAddr
,
err
:=
getGuarantorAddr
(
action
.
db
)
if
err
!=
nil
{
...
...
@@ -986,13 +999,19 @@ func (action *Action) expireLiquidation(coll *pty.Collateralize) (*types.Receipt
coll
.
InvalidRecords
=
append
(
coll
.
InvalidRecords
,
borrowRecord
)
coll
.
BorrowRecords
=
append
(
coll
.
BorrowRecords
[
:
index
],
coll
.
BorrowRecords
[
index
+
1
:
]
...
)
coll
.
CollBalance
-=
borrowRecord
.
CollateralValue
}
else
{
log
:=
action
.
GetFeedReceiptLog
(
coll
,
borrowRecord
)
logs
=
append
(
logs
,
log
)
continue
}
// 还没记录超时告警,记录告警
if
borrowRecord
.
Status
!=
pty
.
CollateralizeUserStatusExpire
{
borrowRecord
.
PreStatus
=
borrowRecord
.
Status
borrowRecord
.
Status
=
pty
.
CollateralizeUserStatusExpire
log
:=
action
.
GetFeedReceiptLog
(
coll
,
borrowRecord
)
logs
=
append
(
logs
,
log
)
}
log
:=
action
.
GetFeedReceiptLog
(
coll
,
borrowRecord
)
logs
=
append
(
logs
,
log
)
}
// 保存
...
...
@@ -1348,14 +1367,12 @@ func queryCollateralizeUserBalanceStatus(db dbm.KV, localdb dbm.KVDB, addr strin
for
{
rows
,
err
=
query
.
List
(
"addr_status"
,
data
,
primary
,
DefaultCount
,
ListDESC
)
if
err
!=
nil
{
clog
.
Debug
(
"queryCollateralizeRecordByAddr.List"
,
"index"
,
"addr"
,
"error"
,
err
)
return
-
1
,
err
}
for
_
,
row
:=
range
rows
{
record
,
err
:=
queryCollateralizeRecordByID
(
db
,
row
.
Data
.
(
*
pty
.
ReceiptCollateralize
)
.
CollateralizeId
,
row
.
Data
.
(
*
pty
.
ReceiptCollateralize
)
.
RecordId
)
if
err
!=
nil
{
clog
.
Debug
(
"queryCollateralizeRecordByStatus.queryCollateralizeRecordByID"
,
"error"
,
err
)
continue
}
totalBalance
+=
record
.
DebtValue
...
...
@@ -1375,21 +1392,27 @@ func queryCollateralizeUserBalance(db dbm.KV, localdb dbm.KVDB, addr string) (in
balance
,
err
:=
queryCollateralizeUserBalanceStatus
(
db
,
localdb
,
addr
,
pty
.
CollateralizeUserStatusCreate
)
if
err
!=
nil
{
clog
.
Error
(
"queryCollateralizeUserBalance"
,
"err"
,
err
)
if
err
!=
types
.
ErrNotFound
{
clog
.
Error
(
"queryCollateralizeUserBalance"
,
"err"
,
err
)
}
}
else
{
totalBalance
+=
balance
}
balance
,
err
=
queryCollateralizeUserBalanceStatus
(
db
,
localdb
,
addr
,
pty
.
CollateralizeUserStatusWarning
)
if
err
!=
nil
{
clog
.
Error
(
"queryCollateralizeUserBalance"
,
"err"
,
err
)
if
err
!=
types
.
ErrNotFound
{
clog
.
Error
(
"queryCollateralizeUserBalance"
,
"err"
,
err
)
}
}
else
{
totalBalance
+=
balance
}
balance
,
err
=
queryCollateralizeUserBalanceStatus
(
db
,
localdb
,
addr
,
pty
.
CollateralizeUserStatusExpire
)
if
err
!=
nil
{
clog
.
Error
(
"queryCollateralizeUserBalance"
,
"err"
,
err
)
if
err
!=
types
.
ErrNotFound
{
clog
.
Error
(
"queryCollateralizeUserBalance"
,
"err"
,
err
)
}
}
else
{
totalBalance
+=
balance
}
...
...
plugin/dapp/collateralize/executor/exec_local.go
View file @
df072618
...
...
@@ -5,6 +5,7 @@
package
executor
import
(
"github.com/33cn/chain33/common/db/table"
//"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
pty
"github.com/33cn/plugin/plugin/dapp/collateralize/types"
...
...
@@ -12,6 +13,7 @@ import (
func
(
c
*
Collateralize
)
execLocal
(
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
)
(
*
types
.
LocalDBSet
,
error
)
{
set
:=
&
types
.
LocalDBSet
{}
var
collTable
,
recordTable
*
table
.
Table
for
_
,
item
:=
range
receipt
.
Logs
{
if
item
.
Ty
>=
pty
.
TyLogCollateralizeCreate
&&
item
.
Ty
<=
pty
.
TyLogCollateralizeRetrieve
{
var
collateralizeLog
pty
.
ReceiptCollateralize
...
...
@@ -21,33 +23,39 @@ func (c *Collateralize) execLocal(tx *types.Transaction, receipt *types.ReceiptD
}
if
item
.
Ty
==
pty
.
TyLogCollateralizeCreate
||
item
.
Ty
==
pty
.
TyLogCollateralizeRetrieve
{
collTable
:
=
pty
.
NewCollateralizeTable
(
c
.
GetLocalDB
())
collTable
=
pty
.
NewCollateralizeTable
(
c
.
GetLocalDB
())
err
=
collTable
.
Replace
(
&
pty
.
ReceiptCollateralize
{
CollateralizeId
:
collateralizeLog
.
CollateralizeId
,
Status
:
collateralizeLog
.
Status
,
AccountAddr
:
collateralizeLog
.
AccountAddr
})
if
err
!=
nil
{
return
nil
,
err
}
kvs
,
err
:=
collTable
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
.
KV
=
append
(
set
.
KV
,
kvs
...
)
}
else
{
recordTable
:
=
pty
.
NewRecordTable
(
c
.
GetLocalDB
())
recordTable
=
pty
.
NewRecordTable
(
c
.
GetLocalDB
())
err
=
recordTable
.
Replace
(
&
pty
.
ReceiptCollateralize
{
CollateralizeId
:
collateralizeLog
.
CollateralizeId
,
Status
:
collateralizeLog
.
Status
,
RecordId
:
collateralizeLog
.
RecordId
,
AccountAddr
:
collateralizeLog
.
AccountAddr
})
if
err
!=
nil
{
return
nil
,
err
}
kvs
,
err
:=
recordTable
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
.
KV
=
append
(
set
.
KV
,
kvs
...
)
}
}
}
if
collTable
!=
nil
{
kvs
,
err
:=
collTable
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
.
KV
=
append
(
set
.
KV
,
kvs
...
)
}
if
recordTable
!=
nil
{
kvs
,
err
:=
recordTable
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
.
KV
=
append
(
set
.
KV
,
kvs
...
)
}
set
.
KV
=
c
.
AddRollbackKV
(
tx
,
[]
byte
(
pty
.
CollateralizeX
),
set
.
KV
)
return
set
,
nil
}
...
...
plugin/dapp/issuance/executor/exec_local.go
View file @
df072618
...
...
@@ -5,6 +5,7 @@
package
executor
import
(
"github.com/33cn/chain33/common/db/table"
//"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
pty
"github.com/33cn/plugin/plugin/dapp/issuance/types"
...
...
@@ -12,6 +13,7 @@ import (
func
(
c
*
Issuance
)
execLocal
(
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
)
(
*
types
.
LocalDBSet
,
error
)
{
set
:=
&
types
.
LocalDBSet
{}
var
IDtable
,
recordTable
*
table
.
Table
for
_
,
item
:=
range
receipt
.
Logs
{
if
item
.
Ty
>=
pty
.
TyLogIssuanceCreate
&&
item
.
Ty
<=
pty
.
TyLogIssuanceClose
{
var
issuanceLog
pty
.
ReceiptIssuance
...
...
@@ -21,32 +23,38 @@ func (c *Issuance) execLocal(tx *types.Transaction, receipt *types.ReceiptData)
}
if
item
.
Ty
==
pty
.
TyLogIssuanceCreate
||
item
.
Ty
==
pty
.
TyLogIssuanceClose
{
IDtable
:
=
pty
.
NewIssuanceTable
(
c
.
GetLocalDB
())
IDtable
=
pty
.
NewIssuanceTable
(
c
.
GetLocalDB
())
err
=
IDtable
.
Replace
(
&
pty
.
ReceiptIssuanceID
{
IssuanceId
:
issuanceLog
.
IssuanceId
,
Status
:
issuanceLog
.
Status
})
if
err
!=
nil
{
return
nil
,
err
}
kvs
,
err
:=
IDtable
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
.
KV
=
append
(
set
.
KV
,
kvs
...
)
}
else
{
recordTable
:
=
pty
.
NewRecordTable
(
c
.
GetLocalDB
())
recordTable
=
pty
.
NewRecordTable
(
c
.
GetLocalDB
())
err
=
recordTable
.
Replace
(
&
pty
.
ReceiptIssuance
{
IssuanceId
:
issuanceLog
.
IssuanceId
,
Status
:
issuanceLog
.
Status
,
DebtId
:
issuanceLog
.
DebtId
,
AccountAddr
:
issuanceLog
.
AccountAddr
})
if
err
!=
nil
{
return
nil
,
err
}
kvs
,
err
:=
recordTable
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
.
KV
=
append
(
set
.
KV
,
kvs
...
)
}
}
}
if
IDtable
!=
nil
{
kvs
,
err
:=
IDtable
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
.
KV
=
append
(
set
.
KV
,
kvs
...
)
}
if
recordTable
!=
nil
{
kvs
,
err
:=
recordTable
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
.
KV
=
append
(
set
.
KV
,
kvs
...
)
}
set
.
KV
=
c
.
AddRollbackKV
(
tx
,
[]
byte
(
pty
.
IssuanceX
),
set
.
KV
)
return
set
,
nil
}
...
...
plugin/dapp/issuance/executor/issuance_test.go
View file @
df072618
...
...
@@ -379,7 +379,7 @@ func TestIssuance(t *testing.T) {
}
p7
:=
&
pkt
.
IssuanceFeedTx
{}
p7
.
Price
=
append
(
p7
.
Price
,
0.2
5
)
p7
.
Price
=
append
(
p7
.
Price
,
0.2
8
)
p7
.
Volume
=
append
(
p7
.
Volume
,
100
)
createTx
,
err
=
pkt
.
CreateRawIssuanceFeedTx
(
env
.
cfg
,
p7
)
if
err
!=
nil
{
...
...
@@ -408,16 +408,89 @@ func TestIssuance(t *testing.T) {
}
// query issuance by status
res
,
err
=
exec
.
Query
(
"IssuanceRecordsByStatus"
,
types
.
Encode
(
&
pkt
.
ReqIssuanceRecords
{
Status
:
2
}))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
res
)
res
,
err
=
exec
.
Query
(
"IssuanceRecordsByStatus"
,
types
.
Encode
(
&
pkt
.
ReqIssuanceRecords
{
Status
:
4
}))
assert
.
Nil
(
t
,
res
)
p8
:=
&
pkt
.
IssuanceFeedTx
{}
p8
.
Price
=
append
(
p8
.
Price
,
0.5
)
p8
.
Volume
=
append
(
p8
.
Volume
,
100
)
createTx
,
err
=
pkt
.
CreateRawIssuanceFeedTx
(
env
.
cfg
,
p8
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
createTx
.
Execer
=
[]
byte
(
pkt
.
IssuanceX
)
createTx
,
err
=
signTx
(
createTx
,
PrivKeyB
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process sign"
,
"err"
,
err
)
}
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
1
,
env
.
difficulty
)
receipt
,
err
=
exec
.
Exec
(
createTx
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
receipt
)
t
.
Log
(
receipt
)
for
_
,
kv
:=
range
receipt
.
KV
{
env
.
db
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptData
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
createTx
,
receiptData
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
set
)
for
_
,
kv
:=
range
set
.
KV
{
env
.
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
// query issuance by status
res
,
err
=
exec
.
Query
(
"IssuanceRecordsByStatus"
,
types
.
Encode
(
&
pkt
.
ReqIssuanceRecords
{
Status
:
4
}))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
res
)
p81
:=
&
pkt
.
IssuanceFeedTx
{}
p81
.
Price
=
append
(
p81
.
Price
,
0.25
)
p81
.
Volume
=
append
(
p81
.
Volume
,
100
)
createTx
,
err
=
pkt
.
CreateRawIssuanceFeedTx
(
env
.
cfg
,
p81
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
createTx
.
Execer
=
[]
byte
(
pkt
.
IssuanceX
)
createTx
,
err
=
signTx
(
createTx
,
PrivKeyB
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process sign"
,
"err"
,
err
)
}
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
1
,
env
.
difficulty
)
receipt
,
err
=
exec
.
Exec
(
createTx
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
receipt
)
t
.
Log
(
receipt
)
for
_
,
kv
:=
range
receipt
.
KV
{
env
.
db
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptData
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
createTx
,
receiptData
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
set
)
for
_
,
kv
:=
range
set
.
KV
{
env
.
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
// query issuance by status
res
,
err
=
exec
.
Query
(
"IssuanceRecordsByStatus"
,
types
.
Encode
(
&
pkt
.
ReqIssuanceRecords
{
Status
:
3
}))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
res
)
res
,
err
=
exec
.
Query
(
"IssuanceRecordsByStatus"
,
types
.
Encode
(
&
pkt
.
ReqIssuanceRecords
{
Status
:
4
}))
assert
.
Nil
(
t
,
res
)
// expire liquidate
p
8
:=
&
pkt
.
IssuanceDebtTx
{
p
9
:=
&
pkt
.
IssuanceDebtTx
{
IssuanceID
:
common
.
ToHex
(
issuanceID
),
Value
:
100
,
}
createTx
,
err
=
pkt
.
CreateRawIssuanceDebtTx
(
env
.
cfg
,
p
8
)
createTx
,
err
=
pkt
.
CreateRawIssuanceDebtTx
(
env
.
cfg
,
p
9
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
...
...
@@ -443,10 +516,10 @@ func TestIssuance(t *testing.T) {
env
.
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
p
9
:=
&
pkt
.
IssuanceFeedTx
{}
p
9
.
Price
=
append
(
p9
.
Price
,
1
)
p
9
.
Volume
=
append
(
p9
.
Volume
,
100
)
createTx
,
err
=
pkt
.
CreateRawIssuanceFeedTx
(
env
.
cfg
,
p
9
)
p
10
:=
&
pkt
.
IssuanceFeedTx
{}
p
10
.
Price
=
append
(
p10
.
Price
,
1
)
p
10
.
Volume
=
append
(
p10
.
Volume
,
100
)
createTx
,
err
=
pkt
.
CreateRawIssuanceFeedTx
(
env
.
cfg
,
p
10
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
...
...
@@ -478,10 +551,10 @@ func TestIssuance(t *testing.T) {
assert
.
NotNil
(
t
,
res
)
// issuance close
p1
0
:=
&
pkt
.
IssuanceCloseTx
{
p1
1
:=
&
pkt
.
IssuanceCloseTx
{
IssuanceID
:
common
.
ToHex
(
issuanceID
),
}
createTx
,
err
=
pkt
.
CreateRawIssuanceCloseTx
(
env
.
cfg
,
p1
0
)
createTx
,
err
=
pkt
.
CreateRawIssuanceCloseTx
(
env
.
cfg
,
p1
1
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
...
...
plugin/dapp/issuance/executor/issuancedb.go
View file @
df072618
...
...
@@ -514,8 +514,10 @@ func (action *Action) IssuanceDebt(debt *pty.IssuanceDebt) (*types.Receipt, erro
}
// 借贷金额不超过个人限额
if
debt
.
GetValue
()
>
issu
.
DebtCeiling
{
clog
.
Error
(
"IssuanceDebt"
,
"CollID"
,
issu
.
IssuanceId
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"debt value"
,
debt
.
GetValue
(),
"error"
,
pty
.
ErrIssuanceExceedDebtCeiling
)
userBalance
,
_
:=
queryIssuanceUserBalance
(
action
.
db
,
action
.
localDB
,
action
.
fromaddr
)
if
debt
.
GetValue
()
+
userBalance
>
issu
.
DebtCeiling
{
clog
.
Error
(
"IssuanceDebt"
,
"CollID"
,
issu
.
IssuanceId
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"debt value"
,
debt
.
GetValue
(),
"current balance"
,
userBalance
,
"error"
,
pty
.
ErrIssuanceExceedDebtCeiling
)
return
nil
,
pty
.
ErrIssuanceExceedDebtCeiling
}
...
...
@@ -706,13 +708,17 @@ func (action *Action) systemLiquidation(issu *pty.Issuance, price int64) (*types
for
index
,
debtRecord
:=
range
issu
.
DebtRecords
{
if
(
debtRecord
.
LiquidationPrice
*
PriceWarningRate
)
/
1e4
<
price
{
// 价格恢复,告警记录恢复
if
debtRecord
.
Status
==
pty
.
IssuanceUserStatusWarning
{
debtRecord
.
PreStatus
=
debtRecord
.
Status
debtRecord
.
Status
=
pty
.
IssuanceUserStatusCreate
log
:=
action
.
GetFeedReceiptLog
(
issu
,
debtRecord
)
logs
=
append
(
logs
,
log
)
}
continue
}
// 价格低于清算线,记录清算
if
debtRecord
.
LiquidationPrice
>=
price
{
getGuarantorAddr
,
err
:=
getGuarantorAddr
(
action
.
db
)
if
err
!=
nil
{
...
...
@@ -737,13 +743,21 @@ func (action *Action) systemLiquidation(issu *pty.Issuance, price int64) (*types
debtRecord
.
Status
=
pty
.
IssuanceUserStatusSystemLiquidate
issu
.
InvalidRecords
=
append
(
issu
.
InvalidRecords
,
debtRecord
)
issu
.
DebtRecords
=
append
(
issu
.
DebtRecords
[
:
index
],
issu
.
DebtRecords
[
index
+
1
:
]
...
)
}
else
{
log
:=
action
.
GetFeedReceiptLog
(
issu
,
debtRecord
)
logs
=
append
(
logs
,
log
)
continue
}
// 价格高于清算线,且还不处于告警状态,记录告警
if
debtRecord
.
Status
!=
pty
.
IssuanceUserStatusWarning
{
debtRecord
.
PreStatus
=
debtRecord
.
Status
debtRecord
.
Status
=
pty
.
IssuanceUserStatusWarning
}
log
:=
action
.
GetFeedReceiptLog
(
issu
,
debtRecord
)
logs
=
append
(
logs
,
log
)
log
:=
action
.
GetFeedReceiptLog
(
issu
,
debtRecord
)
logs
=
append
(
logs
,
log
)
}
}
// 保存
...
...
@@ -767,6 +781,7 @@ func (action *Action) expireLiquidation(issu *pty.Issuance) (*types.Receipt, err
continue
}
// 超过超时时间,记录清算
if
debtRecord
.
ExpireTime
<=
action
.
blocktime
{
getGuarantorAddr
,
err
:=
getGuarantorAddr
(
action
.
db
)
if
err
!=
nil
{
...
...
@@ -791,13 +806,19 @@ func (action *Action) expireLiquidation(issu *pty.Issuance) (*types.Receipt, err
debtRecord
.
Status
=
pty
.
IssuanceUserStatusExpireLiquidate
issu
.
InvalidRecords
=
append
(
issu
.
InvalidRecords
,
debtRecord
)
issu
.
DebtRecords
=
append
(
issu
.
DebtRecords
[
:
index
],
issu
.
DebtRecords
[
index
+
1
:
]
...
)
}
else
{
log
:=
action
.
GetFeedReceiptLog
(
issu
,
debtRecord
)
logs
=
append
(
logs
,
log
)
continue
}
// 还没记录超时告警,记录告警
if
debtRecord
.
Status
!=
pty
.
IssuanceUserStatusExpire
{
debtRecord
.
PreStatus
=
debtRecord
.
Status
debtRecord
.
Status
=
pty
.
IssuanceUserStatusExpire
log
:=
action
.
GetFeedReceiptLog
(
issu
,
debtRecord
)
logs
=
append
(
logs
,
log
)
}
log
:=
action
.
GetFeedReceiptLog
(
issu
,
debtRecord
)
logs
=
append
(
logs
,
log
)
}
// 保存
...
...
@@ -1097,14 +1118,12 @@ func queryIssuanceUserBalanceStatus(db dbm.KV, localdb dbm.KVDB, addr string, st
for
{
rows
,
err
=
query
.
List
(
"addr_status"
,
data
,
primary
,
DefaultCount
,
ListDESC
)
if
err
!=
nil
{
clog
.
Debug
(
"queryIssuanceRecordByAddr.List"
,
"index"
,
"addr"
,
"error"
,
err
)
return
-
1
,
err
}
for
_
,
row
:=
range
rows
{
record
,
err
:=
queryIssuanceRecordByID
(
db
,
row
.
Data
.
(
*
pty
.
ReceiptIssuance
)
.
IssuanceId
,
row
.
Data
.
(
*
pty
.
ReceiptIssuance
)
.
DebtId
)
if
err
!=
nil
{
clog
.
Debug
(
"queryIssuanceRecordByStatus.queryIssuanceRecordByID"
,
"error"
,
err
)
continue
}
totalBalance
+=
record
.
DebtValue
...
...
@@ -1124,21 +1143,27 @@ func queryIssuanceUserBalance(db dbm.KV, localdb dbm.KVDB, addr string) (int64,
balance
,
err
:=
queryIssuanceUserBalanceStatus
(
db
,
localdb
,
addr
,
pty
.
IssuanceUserStatusCreate
)
if
err
!=
nil
{
clog
.
Error
(
"queryIssuanceUserBalance"
,
"err"
,
err
)
if
err
!=
types
.
ErrNotFound
{
clog
.
Error
(
"queryIssuanceUserBalance"
,
"err"
,
err
)
}
}
else
{
totalBalance
+=
balance
}
balance
,
err
=
queryIssuanceUserBalanceStatus
(
db
,
localdb
,
addr
,
pty
.
IssuanceUserStatusWarning
)
if
err
!=
nil
{
clog
.
Error
(
"queryIssuanceUserBalance"
,
"err"
,
err
)
if
err
!=
types
.
ErrNotFound
{
clog
.
Error
(
"queryIssuanceUserBalance"
,
"err"
,
err
)
}
}
else
{
totalBalance
+=
balance
}
balance
,
err
=
queryIssuanceUserBalanceStatus
(
db
,
localdb
,
addr
,
pty
.
IssuanceUserStatusExpire
)
if
err
!=
nil
{
clog
.
Error
(
"queryIssuanceUserBalance"
,
"err"
,
err
)
if
err
!=
types
.
ErrNotFound
{
clog
.
Error
(
"queryIssuanceUserBalance"
,
"err"
,
err
)
}
}
else
{
totalBalance
+=
balance
}
...
...
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