Unverified Commit bbb107d5 authored by vipwzw's avatar vipwzw Committed by GitHub

Merge pull request #793 from jpeng-go/master

#627 上链贷测试问题修复
parents 2552ea42 4ff61287
......@@ -420,7 +420,7 @@ func TestCollateralize(t *testing.T) {
// collateralize liquidate
p7 := &pkt.CollateralizeBorrowTx{
CollateralizeID: common.ToHex(collateralizeID),
Value: 100,
Value: 50,
}
createTx, err = pkt.CreateRawCollateralizeBorrowTx(env.cfg, p7)
if err != nil {
......@@ -448,6 +448,36 @@ func TestCollateralize(t *testing.T) {
env.kvdb.Set(kv.Key, kv.Value)
}
p71 := &pkt.CollateralizeBorrowTx{
CollateralizeID: common.ToHex(collateralizeID),
Value: 50,
}
createTx, err = pkt.CreateRawCollateralizeBorrowTx(env.cfg, p71)
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)
}
p8 := &pkt.CollateralizeFeedTx{}
p8.Price = append(p8.Price, 0.28)
p8.Volume = append(p8.Volume, 100)
......@@ -559,7 +589,7 @@ func TestCollateralize(t *testing.T) {
// expire liquidate
p10 := &pkt.CollateralizeBorrowTx{
CollateralizeID: common.ToHex(collateralizeID),
Value: 100,
Value: 50,
}
createTx, err = pkt.CreateRawCollateralizeBorrowTx(env.cfg, p10)
if err != nil {
......
......@@ -894,12 +894,24 @@ func getGuarantorAddr(db dbm.KV) (string, error) {
return item.GetArr().Value[0], nil
}
func removeLiquidateRecord(borrowRecords []*pty.BorrowRecord, remove pty.BorrowRecord) []*pty.BorrowRecord {
for index, record := range borrowRecords {
if record.RecordId == remove.RecordId {
borrowRecords = append(borrowRecords[:index], borrowRecords[index+1:]...)
break
}
}
return borrowRecords
}
// 系统清算
func (action *Action) systemLiquidation(coll *pty.Collateralize, price int64) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
var removeRecord []*pty.BorrowRecord
for index, borrowRecord := range coll.BorrowRecords {
for _, borrowRecord := range coll.BorrowRecords {
if (borrowRecord.LiquidationPrice*PriceWarningRate)/1e4 < price {
// 价格恢复,告警记录恢复
if borrowRecord.Status == pty.CollateralizeUserStatusWarning {
......@@ -913,6 +925,9 @@ func (action *Action) systemLiquidation(coll *pty.Collateralize, price int64) (*
// 价格低于清算线,记录清算
if borrowRecord.LiquidationPrice >= price {
// 价格低于清算线,记录清算
clog.Debug("systemLiquidation", "coll id", borrowRecord.CollateralizeId, "record id", borrowRecord.RecordId, "account", borrowRecord.AccountAddr, "price", price)
getGuarantorAddr, err := getGuarantorAddr(action.db)
if err != nil {
if err != nil {
......@@ -935,7 +950,7 @@ func (action *Action) systemLiquidation(coll *pty.Collateralize, price int64) (*
borrowRecord.PreStatus = borrowRecord.Status
borrowRecord.Status = pty.CollateralizeUserStatusSystemLiquidate
coll.InvalidRecords = append(coll.InvalidRecords, borrowRecord)
coll.BorrowRecords = append(coll.BorrowRecords[:index], coll.BorrowRecords[index+1:]...)
removeRecord = append(removeRecord, borrowRecord)
coll.CollBalance -= borrowRecord.CollateralValue
log := action.GetFeedReceiptLog(coll, borrowRecord)
......@@ -952,6 +967,11 @@ func (action *Action) systemLiquidation(coll *pty.Collateralize, price int64) (*
}
}
// 删除被清算的记录
for _, record := range removeRecord {
coll.BorrowRecords = removeLiquidateRecord(coll.BorrowRecords, *record)
}
// 保存
coll.LatestLiquidationPrice = getLatestLiquidationPrice(coll)
coll.LatestExpireTime = getLatestExpireTime(coll)
......@@ -967,18 +987,22 @@ func (action *Action) systemLiquidation(coll *pty.Collateralize, price int64) (*
func (action *Action) expireLiquidation(coll *pty.Collateralize) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
var removeRecord []*pty.BorrowRecord
for index, borrowRecord := range coll.BorrowRecords {
for _, borrowRecord := range coll.BorrowRecords {
if borrowRecord.ExpireTime-ExpireWarningTime > action.blocktime {
continue
}
// 超过超时时间,记录清算
if borrowRecord.ExpireTime <= action.blocktime {
// 价格低于清算线,记录清算
clog.Debug("expireLiquidation", "coll id", borrowRecord.CollateralizeId, "record id", borrowRecord.RecordId, "account", borrowRecord.AccountAddr, "time", action.blocktime)
getGuarantorAddr, err := getGuarantorAddr(action.db)
if err != nil {
if err != nil {
clog.Error("systemLiquidation", "getGuarantorAddr", err)
clog.Error("expireLiquidation", "getGuarantorAddr", err)
continue
}
}
......@@ -986,7 +1010,7 @@ func (action *Action) expireLiquidation(coll *pty.Collateralize) (*types.Receipt
// 抵押物转移
receipt, err := action.coinsAccount.ExecTransferFrozen(coll.CreateAddr, getGuarantorAddr, action.execaddr, borrowRecord.CollateralValue)
if err != nil {
clog.Error("systemLiquidation", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", borrowRecord.CollateralValue, "error", err)
clog.Error("expireLiquidation", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", borrowRecord.CollateralValue, "error", err)
continue
}
logs = append(logs, receipt.Logs...)
......@@ -997,7 +1021,7 @@ func (action *Action) expireLiquidation(coll *pty.Collateralize) (*types.Receipt
borrowRecord.PreStatus = borrowRecord.Status
borrowRecord.Status = pty.CollateralizeUserStatusExpireLiquidate
coll.InvalidRecords = append(coll.InvalidRecords, borrowRecord)
coll.BorrowRecords = append(coll.BorrowRecords[:index], coll.BorrowRecords[index+1:]...)
removeRecord = append(removeRecord, borrowRecord)
coll.CollBalance -= borrowRecord.CollateralValue
log := action.GetFeedReceiptLog(coll, borrowRecord)
......@@ -1014,6 +1038,11 @@ func (action *Action) expireLiquidation(coll *pty.Collateralize) (*types.Receipt
}
}
// 删除被清算的记录
for _, record := range removeRecord {
coll.BorrowRecords = removeLiquidateRecord(coll.BorrowRecords, *record)
}
// 保存
coll.LatestLiquidationPrice = getLatestLiquidationPrice(coll)
coll.LatestExpireTime = getLatestExpireTime(coll)
......
......@@ -375,6 +375,19 @@ manage() {
echo "========== # issuance add issuance-manage end =========="
chain33_BlockWait 1 ${MAIN_HTTP}
echo "========== # issuance add issuance-fund begin =========="
tx=$(curl -ksd '{"method":"Chain33.CreateTransaction","params":[{"execer":"manage","actionName":"Modify","payload":{"key": "issuance-fund", "value":"'"${IssuanceAddr1}"'", "op":"add"}}]}' ${MAIN_HTTP} | jq -r ".result")
data=$(curl -ksd '{"method":"Chain33.DecodeRawTransaction","params":[{"txHex":"'"$tx"'"}]}' ${MAIN_HTTP} | jq -r ".result.txs[0]")
ok=$(jq '(.execer != "")' <<<"$data")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
chain33_SignAndSendTx "$tx" ${SystemManager} ${MAIN_HTTP}
echo "========== # issuance add issuance-fund end =========="
chain33_BlockWait 1 ${MAIN_HTTP}
echo "========== # issuance add issuance-price-feed begin =========="
tx=$(curl -ksd '{"method":"Chain33.CreateTransaction","params":[{"execer":"manage","actionName":"Modify","payload":{"key": "issuance-price-feed", "value":"'"${IssuanceAddr2}"'", "op":"add"}}]}' ${MAIN_HTTP} | jq -r ".result")
......
......@@ -30,6 +30,7 @@ type execEnv struct {
db dbm.KV
execAddr string
cfg *types.Chain33Config
ldb dbm.DB
}
var (
......@@ -64,7 +65,7 @@ func initEnv() *execEnv {
cfg := types.NewChain33Config(types.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33")
Init(pkt.IssuanceX, cfg, nil)
_, _, kvdb := util.CreateTestDB()
_, ldb, kvdb := util.CreateTestDB()
accountA := types.Account{
Balance: total,
......@@ -97,6 +98,7 @@ func initEnv() *execEnv {
accA.SetDB(stateDB)
accA.SaveExecAccount(execAddr, &accountA)
manageKeySet("issuance-manage", accountA.Addr, stateDB)
manageKeySet("issuance-fund", accountA.Addr, stateDB)
tokenAccA, _ := account.NewAccountDB(cfg, tokenE.GetName(), pkt.CCNYTokenName, stateDB)
tokenAccA.SaveExecAccount(execAddr, &accountAToken)
......@@ -119,6 +121,7 @@ func initEnv() *execEnv {
db: stateDB,
execAddr: execAddr,
cfg: cfg,
ldb: ldb,
}
}
......@@ -128,7 +131,7 @@ func TestIssuance(t *testing.T) {
// issuance create
p1 := &pkt.IssuanceCreateTx{
TotalBalance: 1000,
DebtCeiling: 100,
DebtCeiling: 200,
LiquidationRatio: 0.25,
Period: 5,
}
......@@ -159,9 +162,7 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
issuanceID := createTx.Hash()
// query issuance by id
res, err := exec.Query("IssuanceInfoByID", types.Encode(&pkt.ReqIssuanceInfo{IssuanceId: common.ToHex(issuanceID)}))
......@@ -204,9 +205,7 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
// query issuance by id
res, err = exec.Query("IssuancePrice", nil)
assert.Nil(t, err)
......@@ -215,6 +214,7 @@ func TestIssuance(t *testing.T) {
// issuance manage
p3 := &pkt.IssuanceManageTx{}
p3.Addr = append(p3.Addr, string(Nodes[1]))
p3.Addr = append(p3.Addr, string(Nodes[2]))
createTx, err = pkt.CreateRawIssuanceManageTx(env.cfg, p3)
if err != nil {
t.Error("RPC_Default_Process", "err", err)
......@@ -232,14 +232,11 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
// issuance debt
p4 := &pkt.IssuanceDebtTx{
......@@ -263,14 +260,11 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
debtID := createTx.Hash()
// query issuance by id
res, err = exec.Query("IssuanceRecordByID",
......@@ -319,14 +313,11 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
// query issuance by status
res, err = exec.Query("IssuanceRecordsByStatus",
types.Encode(&pkt.ReqIssuanceRecords{Status: 6}))
......@@ -350,7 +341,7 @@ func TestIssuance(t *testing.T) {
// issuance liquidate
p6 := &pkt.IssuanceDebtTx{
IssuanceID: common.ToHex(issuanceID),
Value: 100,
Value: 50,
}
createTx, err = pkt.CreateRawIssuanceDebtTx(env.cfg, p6)
if err != nil {
......@@ -369,14 +360,38 @@ func TestIssuance(t *testing.T) {
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)
util.SaveKVList(env.ldb, set.KV)
p61 := &pkt.IssuanceDebtTx{
IssuanceID: common.ToHex(issuanceID),
Value: 50,
}
createTx, err = pkt.CreateRawIssuanceDebtTx(env.cfg, p61)
if err != nil {
t.Error("RPC_Default_Process", "err", err)
}
createTx.Execer = []byte(pkt.IssuanceX)
createTx, err = signTx(createTx, PrivKeyC)
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)
util.SaveKVList(env.ldb, set.KV)
p7 := &pkt.IssuanceFeedTx{}
p7.Price = append(p7.Price, 0.28)
......@@ -398,14 +413,11 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
// query issuance by status
res, err = exec.Query("IssuanceRecordsByStatus",
types.Encode(&pkt.ReqIssuanceRecords{Status: 2}))
......@@ -435,14 +447,11 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
// query issuance by status
res, err = exec.Query("IssuanceRecordsByStatus", types.Encode(&pkt.ReqIssuanceRecords{Status: 4}))
assert.Nil(t, err)
......@@ -468,14 +477,11 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
// query issuance by status
res, err = exec.Query("IssuanceRecordsByStatus",
types.Encode(&pkt.ReqIssuanceRecords{Status: 3}))
......@@ -507,14 +513,11 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
p10 := &pkt.IssuanceFeedTx{}
p10.Price = append(p10.Price, 1)
......@@ -536,14 +539,11 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
// query issuance by status
res, err = exec.Query("IssuanceRecordsByStatus",
types.Encode(&pkt.ReqIssuanceRecords{Status: 5}))
......@@ -571,18 +571,133 @@ func TestIssuance(t *testing.T) {
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)
}
util.SaveKVList(env.ldb, set.KV)
// query issuance by status
res, err = exec.Query("IssuanceByStatus", types.Encode(&pkt.ReqIssuanceByStatus{Status: 2}))
assert.Nil(t, err)
assert.NotNil(t, res)
// issuance create
p12 := &pkt.IssuanceCreateTx{
TotalBalance: 200,
DebtCeiling: 200,
LiquidationRatio: 0.25,
Period: 5,
}
createTx, err = pkt.CreateRawIssuanceCreateTx(env.cfg, p12)
if err != nil {
t.Error("RPC_Default_Process", "err", err)
}
createTx.Execer = []byte(pkt.IssuanceX)
createTx, err = signTx(createTx, PrivKeyA)
if err != nil {
t.Error("RPC_Default_Process sign", "err", err)
}
receipt, err = exec.Exec(createTx, int(1))
assert.Nil(t, err)
assert.NotNil(t, 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)
util.SaveKVList(env.ldb, set.KV)
issuanceID = createTx.Hash()
// query issuance by id
res, err = exec.Query("IssuanceInfoByID", types.Encode(&pkt.ReqIssuanceInfo{IssuanceId: common.ToHex(issuanceID)}))
assert.Nil(t, err)
assert.NotNil(t, res)
// query issuance by status
res, err = exec.Query("IssuanceByStatus", types.Encode(&pkt.ReqIssuanceByStatus{Status: 1}))
assert.Nil(t, err)
assert.NotNil(t, res)
p13 := &pkt.IssuanceDebtTx{
IssuanceID: common.ToHex(issuanceID),
Value: 100,
}
createTx, err = pkt.CreateRawIssuanceDebtTx(env.cfg, p13)
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)
util.SaveKVList(env.ldb, set.KV)
p14 := &pkt.IssuanceFeedTx{}
p14.Price = append(p14.Price, 0.25)
p14.Volume = append(p14.Volume, 100)
createTx, err = pkt.CreateRawIssuanceFeedTx(env.cfg, p14)
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)
util.SaveKVList(env.ldb, set.KV)
// issuance close
p15 := &pkt.IssuanceCloseTx{
IssuanceID: common.ToHex(issuanceID),
}
createTx, err = pkt.CreateRawIssuanceCloseTx(env.cfg, p15)
if err != nil {
t.Error("RPC_Default_Process", "err", err)
}
createTx.Execer = []byte(pkt.IssuanceX)
createTx, err = signTx(createTx, PrivKeyA)
if err != nil {
t.Error("RPC_Default_Process sign", "err", err)
}
exec.SetEnv(env.blockHeight+2, env.blockTime+2, env.difficulty)
receipt, err = exec.Exec(createTx, int(1))
assert.Nil(t, err)
assert.NotNil(t, 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)
util.SaveKVList(env.ldb, set.KV)
}
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
......
......@@ -355,7 +355,7 @@ func (action *Action) IssuanceCreate(create *pty.IssuanceCreate) (*types.Receipt
var receipt *types.Receipt
// 是否配置管理用户
if !isRightAddr(pty.ManageKey, action.fromaddr, action.db) {
if !isRightAddr(pty.FundKey, action.fromaddr, action.db) {
clog.Error("IssuanceCreate", "addr", action.fromaddr, "error", "Address has no permission to create")
return nil, pty.ErrPermissionDeny
}
......@@ -648,7 +648,7 @@ func (action *Action) IssuanceRepay(repay *pty.IssuanceRepay) (*types.Receipt, e
// 检查
if !action.CheckExecTokenAccount(action.fromaddr, debtRecord.DebtValue, false) {
clog.Error("IssuanceRepay", "CollID", issu.IssuanceId, "addr", action.fromaddr, "execaddr", action.execaddr, "error", types.ErrInsufficientBalance)
clog.Error("IssuanceRepay", "CollID", issu.IssuanceId, "addr", action.fromaddr, "execaddr", action.execaddr, "amount", debtRecord.DebtValue, "error", types.ErrInsufficientBalance)
return nil, types.ErrNoBalance
}
......@@ -701,12 +701,24 @@ func (action *Action) IssuanceRepay(repay *pty.IssuanceRepay) (*types.Receipt, e
return receipt, nil
}
func removeLiquidateRecord(debtRecords []*pty.DebtRecord, remove pty.DebtRecord) []*pty.DebtRecord {
for index, record := range debtRecords {
if record.DebtId == remove.DebtId {
debtRecords = append(debtRecords[:index], debtRecords[index+1:]...)
break
}
}
return debtRecords
}
// 系统清算
func (action *Action) systemLiquidation(issu *pty.Issuance, price int64) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
var removeRecord []*pty.DebtRecord
for index, debtRecord := range issu.DebtRecords {
for _, debtRecord := range issu.DebtRecords {
if (debtRecord.LiquidationPrice*PriceWarningRate)/1e4 < price {
// 价格恢复,告警记录恢复
if debtRecord.Status == pty.IssuanceUserStatusWarning {
......@@ -720,6 +732,9 @@ func (action *Action) systemLiquidation(issu *pty.Issuance, price int64) (*types
// 价格低于清算线,记录清算
if debtRecord.LiquidationPrice >= price {
// 价格低于清算线,记录清算
clog.Debug("systemLiquidation", "issuance id", debtRecord.IssuId, "record id", debtRecord.DebtId, "account", debtRecord.AccountAddr, "price", price)
getGuarantorAddr, err := getGuarantorAddr(action.db)
if err != nil {
if err != nil {
......@@ -742,7 +757,7 @@ func (action *Action) systemLiquidation(issu *pty.Issuance, price int64) (*types
debtRecord.PreStatus = debtRecord.Status
debtRecord.Status = pty.IssuanceUserStatusSystemLiquidate
issu.InvalidRecords = append(issu.InvalidRecords, debtRecord)
issu.DebtRecords = append(issu.DebtRecords[:index], issu.DebtRecords[index+1:]...)
removeRecord = append(removeRecord, debtRecord)
log := action.GetFeedReceiptLog(issu, debtRecord)
logs = append(logs, log)
......@@ -760,6 +775,11 @@ func (action *Action) systemLiquidation(issu *pty.Issuance, price int64) (*types
}
}
// 删除被清算的记录
for _, record := range removeRecord {
issu.DebtRecords = removeLiquidateRecord(issu.DebtRecords, *record)
}
// 保存
issu.LatestLiquidationPrice = getLatestLiquidationPrice(issu)
issu.LatestExpireTime = getLatestExpireTime(issu)
......@@ -775,18 +795,22 @@ func (action *Action) systemLiquidation(issu *pty.Issuance, price int64) (*types
func (action *Action) expireLiquidation(issu *pty.Issuance) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
var removeRecord []*pty.DebtRecord
for index, debtRecord := range issu.DebtRecords {
for _, debtRecord := range issu.DebtRecords {
if debtRecord.ExpireTime-ExpireWarningTime > action.blocktime {
continue
}
// 超过超时时间,记录清算
if debtRecord.ExpireTime <= action.blocktime {
// 超过清算线,记录清算
clog.Debug("expireLiquidation", "issuance id", debtRecord.IssuId, "record id", debtRecord.DebtId, "account", debtRecord.AccountAddr, "time", action.blocktime)
getGuarantorAddr, err := getGuarantorAddr(action.db)
if err != nil {
if err != nil {
clog.Error("systemLiquidation", "getGuarantorAddr", err)
clog.Error("expireLiquidation", "getGuarantorAddr", err)
continue
}
}
......@@ -794,7 +818,7 @@ func (action *Action) expireLiquidation(issu *pty.Issuance) (*types.Receipt, err
// 抵押物转移
receipt, err := action.coinsAccount.ExecTransferFrozen(issu.IssuerAddr, getGuarantorAddr, action.execaddr, debtRecord.CollateralValue)
if err != nil {
clog.Error("systemLiquidation", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", debtRecord.CollateralValue, "error", err)
clog.Error("expireLiquidation", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", debtRecord.CollateralValue, "error", err)
continue
}
logs = append(logs, receipt.Logs...)
......@@ -805,7 +829,7 @@ func (action *Action) expireLiquidation(issu *pty.Issuance) (*types.Receipt, err
debtRecord.PreStatus = debtRecord.Status
debtRecord.Status = pty.IssuanceUserStatusExpireLiquidate
issu.InvalidRecords = append(issu.InvalidRecords, debtRecord)
issu.DebtRecords = append(issu.DebtRecords[:index], issu.DebtRecords[index+1:]...)
removeRecord = append(removeRecord, debtRecord)
log := action.GetFeedReceiptLog(issu, debtRecord)
logs = append(logs, log)
......@@ -821,6 +845,11 @@ func (action *Action) expireLiquidation(issu *pty.Issuance) (*types.Receipt, err
}
}
// 删除被清算的记录
for _, record := range removeRecord {
issu.DebtRecords = removeLiquidateRecord(issu.DebtRecords, *record)
}
// 保存
issu.LatestLiquidationPrice = getLatestLiquidationPrice(issu)
issu.LatestExpireTime = getLatestExpireTime(issu)
......@@ -931,8 +960,8 @@ func (action *Action) IssuanceClose(close *pty.IssuanceClose) (*types.Receipt, e
return nil, err
}
if !isRightAddr(pty.ManageKey, action.fromaddr, action.db) {
clog.Error("IssuanceClose", "addr", action.fromaddr, "error", "Address has no permission to close")
if action.fromaddr != issuance.IssuerAddr {
clog.Error("IssuanceClose", "IssuanceId", issuance.IssuanceId, "error", "account error", "create", issuance.IssuerAddr, "from", action.fromaddr)
return nil, pty.ErrPermissionDeny
}
......@@ -944,14 +973,15 @@ func (action *Action) IssuanceClose(close *pty.IssuanceClose) (*types.Receipt, e
}
// 解冻ccny
receipt, err = action.tokenAccount.ExecActive(action.fromaddr, action.execaddr, issuance.Balance)
if err != nil {
clog.Error("IssuanceClose.ExecActive", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", issuance.Balance, "error", err)
return nil, err
if issuance.Balance > 0 {
receipt, err = action.tokenAccount.ExecActive(action.fromaddr, action.execaddr, issuance.Balance)
if err != nil {
clog.Error("IssuanceClose.ExecActive", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", issuance.Balance, "error", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
clog.Debug("IssuanceClose", "ID", close.IssuanceId)
issu := &IssuanceDB{*issuance}
......
......@@ -47,4 +47,5 @@ const (
PriceFeedKey = "issuance-price-feed"
GuarantorKey = "issuance-guarantor"
ManageKey = "issuance-manage"
FundKey = "issuance-fund"
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment