Commit 17a57671 authored by liuyuhang's avatar liuyuhang Committed by 33cn

add test and modify some logic

parent 5b29261b
...@@ -174,7 +174,7 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt ...@@ -174,7 +174,7 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt
} }
// 检查是否已经参与投票 // 检查是否已经参与投票
votes, err := a.checkVotesRecord(voteProb.ProposalID) votes, err := a.checkVotesRecord(votesRecord(voteProb.ProposalID))
if err != nil { if err != nil {
alog.Error("votePropBoard ", "addr", a.fromaddr, "execaddr", a.execaddr, "checkVotesRecord failed", alog.Error("votePropBoard ", "addr", a.fromaddr, "execaddr", a.execaddr, "checkVotesRecord failed",
voteProb.ProposalID, "err", err) voteProb.ProposalID, "err", err)
...@@ -205,13 +205,8 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt ...@@ -205,13 +205,8 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kv []*types.KeyValue var kv []*types.KeyValue
if cur.VoteResult.TotalVotes != 0 && // 首次进入投票期,即将提案金转入自治系统地址
cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes != 0 && if cur.Status == auty.AutonomyStatusProposalBoard {
float32(cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes) / float32(cur.VoteResult.TotalVotes) >= float32(pubAttendRatio)/100.0 &&
float32(cur.VoteResult.ApproveVotes) / float32(cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes) >= float32(pubApproveRatio)/100.0 {
cur.VoteResult.Pass = true
cur.PropBoard.RealEndBlockHeight = a.height
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.CurRule.ProposalAmount) receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil { if err != nil {
alog.Error("votePropBoard ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err) alog.Error("votePropBoard ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
...@@ -221,6 +216,14 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt ...@@ -221,6 +216,14 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt
kv = append(kv, receipt.KV...) kv = append(kv, receipt.KV...)
} }
if cur.VoteResult.TotalVotes != 0 &&
cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes != 0 &&
float32(cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes) / float32(cur.VoteResult.TotalVotes) >= float32(pubAttendRatio)/100.0 &&
float32(cur.VoteResult.ApproveVotes) / float32(cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes) >= float32(pubApproveRatio)/100.0 {
cur.VoteResult.Pass = true
cur.PropBoard.RealEndBlockHeight = a.height
}
key := propBoardID(voteProb.ProposalID) key := propBoardID(voteProb.ProposalID)
cur.Status = auty.AutonomyStatusVotePropBoard cur.Status = auty.AutonomyStatusVotePropBoard
if cur.VoteResult.Pass { if cur.VoteResult.Pass {
...@@ -229,7 +232,7 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt ...@@ -229,7 +232,7 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt
kv = append(kv, &types.KeyValue{Key: key, Value: types.Encode(cur)}) kv = append(kv, &types.KeyValue{Key: key, Value: types.Encode(cur)})
// 更新VotesRecord // 更新VotesRecord
kv = append(kv, &types.KeyValue{Key: VotesRecord(voteProb.ProposalID), Value: types.Encode(votes)}) kv = append(kv, &types.KeyValue{Key: votesRecord(voteProb.ProposalID), Value: types.Encode(votes)})
// 更新当前具有权利的董事会成员 // 更新当前具有权利的董事会成员
if cur.VoteResult.Pass { if cur.VoteResult.Pass {
...@@ -291,6 +294,9 @@ func (a *action) tmintPropBoard(tmintProb *auty.TerminateProposalBoard) (*types. ...@@ -291,6 +294,9 @@ func (a *action) tmintPropBoard(tmintProb *auty.TerminateProposalBoard) (*types.
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kv []*types.KeyValue var kv []*types.KeyValue
// 未进行投票情况下,符合提案关闭的也需要扣除提案费用
if cur.Status == auty.AutonomyStatusProposalBoard {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.CurRule.ProposalAmount) receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil { if err != nil {
alog.Error("votePropBoard ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err) alog.Error("votePropBoard ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
...@@ -298,6 +304,7 @@ func (a *action) tmintPropBoard(tmintProb *auty.TerminateProposalBoard) (*types. ...@@ -298,6 +304,7 @@ func (a *action) tmintPropBoard(tmintProb *auty.TerminateProposalBoard) (*types.
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...) kv = append(kv, receipt.KV...)
}
cur.Status = auty.AutonomyStatusTmintPropBoard cur.Status = auty.AutonomyStatusTmintPropBoard
...@@ -369,9 +376,9 @@ func (a *action) getActiveRule() (*auty.RuleConfig, error) { ...@@ -369,9 +376,9 @@ func (a *action) getActiveRule() (*auty.RuleConfig, error) {
return rule, nil return rule, nil
} }
func (a *action) checkVotesRecord(ID string) (*auty.VotesRecord, error) { func (a *action) checkVotesRecord(key []byte) (*auty.VotesRecord, error) {
var votes auty.VotesRecord var votes auty.VotesRecord
value, err := a.db.Get(VotesRecord(ID)) value, err := a.db.Get(key)
if err == nil { if err == nil {
err = types.Decode(value, &votes) err = types.Decode(value, &votes)
if err != nil { if err != nil {
......
...@@ -17,7 +17,7 @@ var ( ...@@ -17,7 +17,7 @@ var (
localPrefix = "LOCDB" + auty.AutonomyX + "-" localPrefix = "LOCDB" + auty.AutonomyX + "-"
) )
func VotesRecord(txHash string) []byte { func votesRecord(txHash string) []byte {
return []byte(fmt.Sprintf("%s%s", votesRecordPrefix, txHash)) return []byte(fmt.Sprintf("%s%s", votesRecordPrefix, txHash))
} }
...@@ -25,6 +25,7 @@ var ( ...@@ -25,6 +25,7 @@ var (
// board // board
boardPrefix = idPrefix + "board" + "-" boardPrefix = idPrefix + "board" + "-"
localBoardPrefix = localPrefix + "board" + "-" localBoardPrefix = localPrefix + "board" + "-"
boardVotesRecordPrefix = boardPrefix + "vote" + "-"
) )
func activeBoardID() []byte { func activeBoardID() []byte {
...@@ -35,6 +36,10 @@ func propBoardID(txHash string) []byte { ...@@ -35,6 +36,10 @@ func propBoardID(txHash string) []byte {
return []byte(fmt.Sprintf("%s%s", boardPrefix, txHash)) return []byte(fmt.Sprintf("%s%s", boardPrefix, txHash))
} }
func boardVotesRecord(txHash string) []byte {
return []byte(fmt.Sprintf("%s%s", boardVotesRecordPrefix, txHash))
}
func calcBoardKey4StatusHeight(status int32, heightindex string) []byte { func calcBoardKey4StatusHeight(status int32, heightindex string) []byte {
key := fmt.Sprintf(localBoardPrefix + "%d-" +"%s", status, heightindex) key := fmt.Sprintf(localBoardPrefix + "%d-" +"%s", status, heightindex)
return []byte(key) return []byte(key)
......
...@@ -142,7 +142,7 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec ...@@ -142,7 +142,7 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
start := cur.GetPropProject().StartBlockHeight start := cur.GetPropProject().StartBlockHeight
end := cur.GetPropProject().EndBlockHeight end := cur.GetPropProject().EndBlockHeight
real := cur.GetPropProject().RealEndBlockHeight real := cur.GetPropProject().RealEndBlockHeight
if start < a.height || end < a.height || (real != 0 && real < a.height) { if a.height < start || a.height > end || real != 0 {
err := auty.ErrVotePeriod err := auty.ErrVotePeriod
alog.Error("votePropProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "ProposalID", alog.Error("votePropProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "ProposalID",
voteProb.ProposalID, "err", err) voteProb.ProposalID, "err", err)
...@@ -154,6 +154,7 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec ...@@ -154,6 +154,7 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
for _, addr := range cur.Boards { for _, addr := range cur.Boards {
if addr == a.fromaddr { if addr == a.fromaddr {
isBoard = true isBoard = true
break
} }
} }
if !isBoard { if !isBoard {
...@@ -164,9 +165,9 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec ...@@ -164,9 +165,9 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
} }
// 检查是否已经参与投票 // 检查是否已经参与投票
votes, err := a.checkVotesRecord(voteProb.ProposalID) votes, err := a.checkVotesRecord(boardVotesRecord(voteProb.ProposalID))
if err != nil { if err != nil {
alog.Error("votePropProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "checkVotesRecord failed", alog.Error("votePropProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "checkVotesRecord boardVotesRecord failed",
voteProb.ProposalID, "err", err) voteProb.ProposalID, "err", err)
return nil, err return nil, err
} }
...@@ -174,7 +175,6 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec ...@@ -174,7 +175,6 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
// 更新已经投票地址 // 更新已经投票地址
votes.Address = append(votes.Address, a.fromaddr) votes.Address = append(votes.Address, a.fromaddr)
// 更新投票结果 // 更新投票结果
cur.BoardVoteRes.TotalVotes = int32(len(cur.Boards))
if voteProb.Approve { if voteProb.Approve {
cur.BoardVoteRes.ApproveVotes += 1 cur.BoardVoteRes.ApproveVotes += 1
} else { } else {
...@@ -184,12 +184,8 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec ...@@ -184,12 +184,8 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kv []*types.KeyValue var kv []*types.KeyValue
if cur.BoardVoteRes.TotalVotes != 0 && // 首次进入投票期,即将提案金转入自治系统地址
cur.BoardVoteRes.ApproveVotes + cur.BoardVoteRes.OpposeVotes != 0 && if cur.Status == auty.AutonomyStatusProposalProject {
float32(cur.BoardVoteRes.ApproveVotes + cur.BoardVoteRes.OpposeVotes) / float32(cur.BoardVoteRes.TotalVotes) >= float32(cur.CurRule.BoardAttendRatio)/100.0 &&
float32(cur.BoardVoteRes.ApproveVotes) / float32(cur.BoardVoteRes.ApproveVotes + cur.BoardVoteRes.OpposeVotes) >= float32(cur.CurRule.BoardApproveRatio)/100.0 {
cur.BoardVoteRes.Pass = true
cur.PropProject.RealEndBlockHeight = a.height
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.CurRule.ProposalAmount) receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil { if err != nil {
alog.Error("votePropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err) alog.Error("votePropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
...@@ -199,6 +195,14 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec ...@@ -199,6 +195,14 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
kv = append(kv, receipt.KV...) kv = append(kv, receipt.KV...)
} }
if cur.BoardVoteRes.TotalVotes != 0 &&
cur.BoardVoteRes.ApproveVotes + cur.BoardVoteRes.OpposeVotes != 0 &&
float32(cur.BoardVoteRes.ApproveVotes + cur.BoardVoteRes.OpposeVotes) / float32(cur.BoardVoteRes.TotalVotes) >= float32(cur.CurRule.BoardAttendRatio)/100.0 &&
float32(cur.BoardVoteRes.ApproveVotes) / float32(cur.BoardVoteRes.ApproveVotes + cur.BoardVoteRes.OpposeVotes) >= float32(cur.CurRule.BoardApproveRatio)/100.0 {
cur.BoardVoteRes.Pass = true
cur.PropProject.RealEndBlockHeight = a.height
}
key := propProjectID(voteProb.ProposalID) key := propProjectID(voteProb.ProposalID)
cur.Status = auty.AutonomyStatusVotePropProject cur.Status = auty.AutonomyStatusVotePropProject
if cur.BoardVoteRes.Pass { if cur.BoardVoteRes.Pass {
...@@ -209,9 +213,9 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec ...@@ -209,9 +213,9 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
} else { } else {
cur.Status = auty.AutonomyStatusTmintPropProject cur.Status = auty.AutonomyStatusTmintPropProject
// 提案通过,将工程金额从基金付款给承包商 // 提案通过,将工程金额从基金付款给承包商
receipt, err := a.coinsAccount.ExecTransferFrozen(autonomyAddr, cur.PropProject.ToAddr, a.execaddr, cur.PropProject.Amount) receipt, err := a.coinsAccount.ExecTransfer(autonomyAddr, cur.PropProject.ToAddr, a.execaddr, cur.PropProject.Amount)
if err != nil { if err != nil {
alog.Error("votePropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen to contractor fail", err) alog.Error("votePropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransfer to contractor project amount fail", err)
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
...@@ -221,7 +225,7 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec ...@@ -221,7 +225,7 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
kv = append(kv, &types.KeyValue{Key: key, Value: types.Encode(cur)}) kv = append(kv, &types.KeyValue{Key: key, Value: types.Encode(cur)})
// 更新VotesRecord // 更新VotesRecord
kv = append(kv, &types.KeyValue{Key: VotesRecord(voteProb.ProposalID), Value: types.Encode(votes)}) kv = append(kv, &types.KeyValue{Key: boardVotesRecord(voteProb.ProposalID), Value: types.Encode(votes)})
ty := auty.TyLogVotePropProject ty := auty.TyLogVotePropProject
if cur.BoardVoteRes.Pass { if cur.BoardVoteRes.Pass {
...@@ -265,7 +269,7 @@ func (a *action) pubVotePropProject(voteProb *auty.PubVoteProposalProject) (*typ ...@@ -265,7 +269,7 @@ func (a *action) pubVotePropProject(voteProb *auty.PubVoteProposalProject) (*typ
} }
// 检查是否已经参与投票 // 检查是否已经参与投票
votes, err := a.checkVotesRecord(voteProb.ProposalID) votes, err := a.checkVotesRecord(votesRecord(voteProb.ProposalID))
if err != nil { if err != nil {
alog.Error("pubVotePropProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "checkVotesRecord failed", alog.Error("pubVotePropProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "checkVotesRecord failed",
voteProb.ProposalID, "err", err) voteProb.ProposalID, "err", err)
...@@ -274,7 +278,7 @@ func (a *action) pubVotePropProject(voteProb *auty.PubVoteProposalProject) (*typ ...@@ -274,7 +278,7 @@ func (a *action) pubVotePropProject(voteProb *auty.PubVoteProposalProject) (*typ
// 更新投票记录 // 更新投票记录
votes.Address = append(votes.Address, a.fromaddr) votes.Address = append(votes.Address, a.fromaddr)
if cur.GetBoardVoteRes().TotalVotes == 0 { //需要统计总票数 if cur.GetPubVote().TotalVotes == 0 { //需要统计总票数
addr := "16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp" addr := "16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
account, err := a.getStartHeightVoteAccount(addr, start) account, err := a.getStartHeightVoteAccount(addr, start)
if err != nil { if err != nil {
...@@ -296,17 +300,9 @@ func (a *action) pubVotePropProject(voteProb *auty.PubVoteProposalProject) (*typ ...@@ -296,17 +300,9 @@ func (a *action) pubVotePropProject(voteProb *auty.PubVoteProposalProject) (*typ
var kv []*types.KeyValue var kv []*types.KeyValue
if cur.PubVote.TotalVotes != 0 && if cur.PubVote.TotalVotes != 0 &&
float32(cur.PubVote.OpposeVotes) / float32(cur.PubVote.TotalVotes) >= float32(cur.CurRule.PubOpposeRatio) { float32(cur.PubVote.OpposeVotes) / float32(cur.PubVote.TotalVotes) >= float32(cur.CurRule.PubOpposeRatio) / 100.0 {
cur.PubVote.PubPass = false cur.PubVote.PubPass = false
cur.PropProject.RealEndBlockHeight = a.height cur.PropProject.RealEndBlockHeight = a.height
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil {
alog.Error("pubVotePropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
} }
key := propProjectID(voteProb.ProposalID) key := propProjectID(voteProb.ProposalID)
...@@ -319,7 +315,7 @@ func (a *action) pubVotePropProject(voteProb *auty.PubVoteProposalProject) (*typ ...@@ -319,7 +315,7 @@ func (a *action) pubVotePropProject(voteProb *auty.PubVoteProposalProject) (*typ
kv = append(kv, &types.KeyValue{Key: key, Value: types.Encode(cur)}) kv = append(kv, &types.KeyValue{Key: key, Value: types.Encode(cur)})
// 更新VotesRecord // 更新VotesRecord
kv = append(kv, &types.KeyValue{Key: VotesRecord(voteProb.ProposalID), Value: types.Encode(votes)}) kv = append(kv, &types.KeyValue{Key: votesRecord(voteProb.ProposalID), Value: types.Encode(votes)})
receiptLog := getProjectReceiptLog(pre, cur, int32(ty)) receiptLog := getProjectReceiptLog(pre, cur, int32(ty))
logs = append(logs, receiptLog) logs = append(logs, receiptLog)
...@@ -346,7 +342,7 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty ...@@ -346,7 +342,7 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty
// 公示期间不能终止 // 公示期间不能终止
if cur.PubVote.Publicity && cur.PubVote.PubPass && if cur.PubVote.Publicity && cur.PubVote.PubPass &&
a.height <= cur.PropProject.EndBlockHeight + publicPeriod { a.height <= cur.PropProject.RealEndBlockHeight + publicPeriod {
err := auty.ErrTerminatePeriod err := auty.ErrTerminatePeriod
alog.Error("tmintPropProject ", "addr", a.fromaddr, "status", cur.Status, alog.Error("tmintPropProject ", "addr", a.fromaddr, "status", cur.Status,
"in publicity vote period can not terminate", tmintProb.ProposalID, "err", err) "in publicity vote period can not terminate", tmintProb.ProposalID, "err", err)
...@@ -356,7 +352,7 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty ...@@ -356,7 +352,7 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty
// 董事会投票期间不能终止 // 董事会投票期间不能终止
start := cur.GetPropProject().StartBlockHeight start := cur.GetPropProject().StartBlockHeight
end := cur.GetPropProject().EndBlockHeight end := cur.GetPropProject().EndBlockHeight
if !cur.PubVote.Publicity && a.height < end && !cur.BoardVoteRes.Pass { if !cur.BoardVoteRes.Pass && a.height <= end {
err := auty.ErrTerminatePeriod err := auty.ErrTerminatePeriod
alog.Error("tmintPropProject ", "addr", a.fromaddr, "status", cur.Status, "height", a.height, alog.Error("tmintPropProject ", "addr", a.fromaddr, "status", cur.Status, "height", a.height,
"in board vote period can not terminate", tmintProb.ProposalID, "err", err) "in board vote period can not terminate", tmintProb.ProposalID, "err", err)
...@@ -382,7 +378,7 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty ...@@ -382,7 +378,7 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty
cur.PubVote.TotalVotes = int32(account.Balance/ticketPrice) cur.PubVote.TotalVotes = int32(account.Balance/ticketPrice)
} }
if cur.PubVote.TotalVotes != 0 && if cur.PubVote.TotalVotes != 0 &&
float32(cur.PubVote.OpposeVotes) / float32(cur.PubVote.TotalVotes) >= float32(cur.CurRule.PubOpposeRatio) { float32(cur.PubVote.OpposeVotes) / float32(cur.PubVote.TotalVotes) >= float32(cur.CurRule.PubOpposeRatio)/ 100.0 {
cur.PubVote.PubPass = false cur.PubVote.PubPass = false
} }
} }
...@@ -391,20 +387,24 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty ...@@ -391,20 +387,24 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kv []*types.KeyValue var kv []*types.KeyValue
// 如果为提案状态,则判断是否需要扣除提案费
if cur.Status == auty.AutonomyStatusProposalProject && a.height > end {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.CurRule.ProposalAmount) receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil { if err != nil {
alog.Error("tmintPropProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err) alog.Error("votePropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...) kv = append(kv, receipt.KV...)
}
if (cur.PubVote.Publicity && cur.PubVote.PubPass) || // 需要公示且公示通过 if (cur.PubVote.Publicity && cur.PubVote.PubPass) || // 需要公示且公示通过
(!cur.PubVote.Publicity && cur.BoardVoteRes.Pass){ // 不需要公示且董事会通过 (!cur.PubVote.Publicity && cur.BoardVoteRes.Pass){ // 不需要公示且董事会通过
// 提案通过,将工程金额从基金付款给承包商 // 提案通过,将工程金额从基金付款给承包商
receipt, err := a.coinsAccount.ExecTransferFrozen(autonomyAddr, cur.PropProject.ToAddr, a.execaddr, cur.PropProject.Amount) receipt, err := a.coinsAccount.ExecTransfer(autonomyAddr, cur.PropProject.ToAddr, a.execaddr, cur.PropProject.Amount)
if err != nil { if err != nil {
alog.Error("tmintPropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen to contractor fail", err) alog.Error("tmintPropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransfer to contractor project amount fail", err)
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
......
...@@ -28,7 +28,11 @@ import ( ...@@ -28,7 +28,11 @@ import (
// testLargeProjectAmount int64 = 1 // testLargeProjectAmount int64 = 1
//) //)
func InitProject(stateDB dbm.KV) { const (
testProjectAmount int64 = types.Coin * 100 // 工程需要资金
)
func InitBoard(stateDB dbm.KV) {
// add active board // add active board
board := &auty.ProposalBoard{ board := &auty.ProposalBoard{
Year: 2019, Year: 2019,
...@@ -42,6 +46,18 @@ func InitProject(stateDB dbm.KV) { ...@@ -42,6 +46,18 @@ func InitProject(stateDB dbm.KV) {
stateDB.Set(activeBoardID(), types.Encode(board)) stateDB.Set(activeBoardID(), types.Encode(board))
} }
func InitRule(stateDB dbm.KV) {
// add active rule
rule := &auty.RuleConfig{
BoardAttendRatio: boardAttendRatio,
BoardApproveRatio: boardApproveRatio,
PubOpposeRatio: pubOpposeRatio,
ProposalAmount: proposalAmount,
LargeProjectAmount: types.Coin *100,
}
stateDB.Set(activeRuleID(), types.Encode(rule))
}
func TestPropProject(t *testing.T) { func TestPropProject(t *testing.T) {
env, exec, _, _ := InitEnv() env, exec, _, _ := InitEnv()
...@@ -92,7 +108,7 @@ func TestPropProject(t *testing.T) { ...@@ -92,7 +108,7 @@ func TestPropProject(t *testing.T) {
func TestRevokeProposalProject(t *testing.T) { func TestRevokeProposalProject(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv() env, exec, stateDB, kvdb := InitEnv()
InitProject(stateDB) InitBoard(stateDB)
// PropProject // PropProject
testPropProject(t, env, exec, stateDB, kvdb, true) testPropProject(t, env, exec, stateDB, kvdb, true)
//RevokeProposalProject //RevokeProposalProject
...@@ -101,16 +117,33 @@ func TestRevokeProposalProject(t *testing.T) { ...@@ -101,16 +117,33 @@ func TestRevokeProposalProject(t *testing.T) {
func TestVoteProposalProject(t *testing.T) { func TestVoteProposalProject(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv() env, exec, stateDB, kvdb := InitEnv()
InitProject(stateDB) InitBoard(stateDB)
// PropProject // PropProject
testPropProject(t, env, exec, stateDB, kvdb, true) testPropProject(t, env, exec, stateDB, kvdb, true)
//voteProposalProject //voteProposalProject
voteProposalProject(t, env, exec, stateDB, kvdb, true) voteProposalProject(t, env, exec, stateDB, kvdb, true)
// check
checkVoteProposalProjectResult(t, stateDB, env.txHash)
}
func TestPubVoteProposalProject(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv()
InitBoard(stateDB)
InitRule(stateDB)
// PropProject
testPropProject(t, env, exec, stateDB, kvdb, true)
// voteProposalProject
voteProposalProject(t, env, exec, stateDB, kvdb, true)
// pubVoteProposalProject
pubVoteProposalProject(t, env, exec, stateDB, kvdb, true) // 未通过全体持票人投票
// terminate
// check
checkPubVoteProposalProjectResult(t, stateDB, env.txHash)
} }
func TestTerminateProposalProject(t *testing.T) { func TestTerminateProposalProject(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv() env, exec, stateDB, kvdb := InitEnv()
InitProject(stateDB) InitBoard(stateDB)
// PropProject // PropProject
testPropProject(t, env, exec, stateDB, kvdb, true) testPropProject(t, env, exec, stateDB, kvdb, true)
//terminateProposalProject //terminateProposalProject
...@@ -122,7 +155,7 @@ func testPropProject(t *testing.T, env *execEnv, exec drivers.Driver, stateDB db ...@@ -122,7 +155,7 @@ func testPropProject(t *testing.T, env *execEnv, exec drivers.Driver, stateDB db
Year: 2019, Year: 2019,
Month: 7, Month: 7,
Day: 10, Day: 10,
Amount: types.Coin * 100, Amount: testProjectAmount,
ToAddr: AddrD, ToAddr: AddrD,
StartBlockHeight: env.blockHeight + 5, StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + 10, EndBlockHeight: env.blockHeight + 10,
...@@ -261,9 +294,9 @@ func voteProposalProject(t *testing.T, env *execEnv, exec drivers.Driver, stateD ...@@ -261,9 +294,9 @@ func voteProposalProject(t *testing.T, env *execEnv, exec drivers.Driver, stateD
} }
records := []record{ records := []record{
{PrivKeyA, false}, {PrivKeyA, false},
{PrivKeyB, false}, {PrivKeyB, true},
{PrivKeyC, true}, {PrivKeyC, true},
{PrivKeyD, true}, //{PrivKeyD, true},
} }
for _, record := range records { for _, record := range records {
...@@ -306,6 +339,20 @@ func voteProposalProject(t *testing.T, env *execEnv, exec drivers.Driver, stateD ...@@ -306,6 +339,20 @@ func voteProposalProject(t *testing.T, env *execEnv, exec drivers.Driver, stateD
api.On("StoreGet", mock.Anything).Return(&types.StoreReplyValue{Values:values}, nil).Once() api.On("StoreGet", mock.Anything).Return(&types.StoreReplyValue{Values:values}, nil).Once()
exec.SetAPI(api) exec.SetAPI(api)
} }
}
func voteProposalProjectTx(parm *auty.VoteProposalProject) (*types.Transaction, error) {
if parm == nil {
return nil, types.ErrInvalidParam
}
val := &auty.AutonomyAction{
Ty: auty.AutonomyActionVotePropProject,
Value: &auty.AutonomyAction_VotePropProject{VotePropProject: parm},
}
return types.CreateFormatTx(types.ExecName(auty.AutonomyX), types.Encode(val))
}
func checkVoteProposalProjectResult(t *testing.T, stateDB dbm.KV, proposalID string) {
// check // check
// balance // balance
accCoin := account.NewCoinsAccount() accCoin := account.NewCoinsAccount()
...@@ -313,7 +360,7 @@ func voteProposalProject(t *testing.T, env *execEnv, exec drivers.Driver, stateD ...@@ -313,7 +360,7 @@ func voteProposalProject(t *testing.T, env *execEnv, exec drivers.Driver, stateD
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX)) account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
require.Equal(t, int64(0), account.Frozen) require.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyAddr, address.ExecAddress(auty.AutonomyX)) account = accCoin.LoadExecAccount(autonomyAddr, address.ExecAddress(auty.AutonomyX))
require.Equal(t, int64(proposalAmount), account.Balance) require.Equal(t, int64(proposalAmount) - testProjectAmount, account.Balance)
// status // status
value, err := stateDB.Get(propProjectID(proposalID)) value, err := stateDB.Get(propProjectID(proposalID))
require.NoError(t, err) require.NoError(t, err)
...@@ -322,23 +369,114 @@ func voteProposalProject(t *testing.T, env *execEnv, exec drivers.Driver, stateD ...@@ -322,23 +369,114 @@ func voteProposalProject(t *testing.T, env *execEnv, exec drivers.Driver, stateD
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, int32(auty.AutonomyStatusTmintPropProject), cur.Status) require.Equal(t, int32(auty.AutonomyStatusTmintPropProject), cur.Status)
require.Equal(t, AddrA, cur.Address) require.Equal(t, AddrA, cur.Address)
//require.Equal(t, true, cur.VoteResult.Pass) }
// check Project
au := &Autonomy{ func pubVoteProposalProject(t *testing.T, env *execEnv, exec drivers.Driver, stateDB dbm.KV, kvdb dbm.KVDB, save bool) {
drivers.DriverBase{}, api := new(apimock.QueueProtocolAPI)
api.On("StoreList", mock.Anything).Return(&types.StoreListReply{}, nil)
api.On("GetLastHeader", mock.Anything).Return(&types.Header{StateHash: []byte("")}, nil)
hear := &types.Header{StateHash: []byte("")}
api.On("GetHeaders", mock.Anything).
Return(&types.Headers{
Items:[]*types.Header{hear}}, nil)
acc := &types.Account{
Currency: 0,
Balance: total*4,
}
val := types.Encode(acc)
values := [][]byte{val}
api.On("StoreGet", mock.Anything).Return(&types.StoreReplyValue{Values:values}, nil).Once()
acc = &types.Account{
Currency: 0,
Balance: total,
}
val1 := types.Encode(acc)
values1 := [][]byte{val1}
api.On("StoreGet", mock.Anything).Return(&types.StoreReplyValue{Values:values1}, nil).Once()
exec.SetAPI(api)
proposalID := env.txHash
// 4人参与投票,3人赞成票,1人反对票
type record struct {
priv string
appr bool
}
records := []record{
{PrivKeyA, true},
{PrivKeyB, false},
{PrivKeyC, true},
//{PrivKeyD, true},
}
for _, record := range records {
opt := &auty.PubVoteProposalProject{
ProposalID:proposalID,
Oppose: record.appr,
}
tx, err := pubVoteProposalProjectTx(opt)
require.NoError(t, err)
tx, err = signTx(tx, record.priv)
require.NoError(t, err)
// 设定当前高度为投票高度
exec.SetEnv(env.startHeight, env.blockTime, env.difficulty)
receipt, err := exec.Exec(tx, int(1))
require.NoError(t, err)
require.NotNil(t, receipt)
if save {
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
}
receiptData := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err := exec.ExecLocal(tx, receiptData, int(1))
require.NoError(t, err)
require.NotNil(t, set)
if save {
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
}
// 每次需要重新设置
acc := &types.Account{
Currency: 0,
Balance: total,
}
val := types.Encode(acc)
values := [][]byte{val}
api.On("StoreGet", mock.Anything).Return(&types.StoreReplyValue{Values:values}, nil).Once()
exec.SetAPI(api)
} }
au.SetStateDB(stateDB)
au.SetLocalDB(kvdb)
//action := newAction(au, &types.Transaction{}, 0)
} }
func voteProposalProjectTx(parm *auty.VoteProposalProject) (*types.Transaction, error) { func checkPubVoteProposalProjectResult(t *testing.T, stateDB dbm.KV, proposalID string) {
// check
// balance
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
require.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyAddr, address.ExecAddress(auty.AutonomyX))
require.Equal(t, int64(proposalAmount), account.Balance)
// status
value, err := stateDB.Get(propProjectID(proposalID))
require.NoError(t, err)
cur := &auty.AutonomyProposalProject{}
err = types.Decode(value, cur)
require.NoError(t, err)
require.Equal(t, int32(auty.AutonomyStatusTmintPropProject), cur.Status)
require.Equal(t, AddrA, cur.Address)
}
func pubVoteProposalProjectTx(parm *auty.PubVoteProposalProject) (*types.Transaction, error) {
if parm == nil { if parm == nil {
return nil, types.ErrInvalidParam return nil, types.ErrInvalidParam
} }
val := &auty.AutonomyAction{ val := &auty.AutonomyAction{
Ty: auty.AutonomyActionVotePropProject, Ty: auty.AutonomyActionPubVotePropProject,
Value: &auty.AutonomyAction_VotePropProject{VotePropProject: parm}, Value: &auty.AutonomyAction_PubVotePropProject{PubVotePropProject: parm},
} }
return types.CreateFormatTx(types.ExecName(auty.AutonomyX), types.Encode(val)) return types.CreateFormatTx(types.ExecName(auty.AutonomyX), types.Encode(val))
} }
......
...@@ -143,7 +143,7 @@ func (a *action) votePropRule(voteProb *auty.VoteProposalRule) (*types.Receipt, ...@@ -143,7 +143,7 @@ func (a *action) votePropRule(voteProb *auty.VoteProposalRule) (*types.Receipt,
} }
// 检查是否已经参与投票 // 检查是否已经参与投票
votes, err := a.checkVotesRecord(voteProb.ProposalID) votes, err := a.checkVotesRecord(votesRecord(voteProb.ProposalID))
if err != nil { if err != nil {
alog.Error("votePropRule ", "addr", a.fromaddr, "execaddr", a.execaddr, "checkVotesRecord failed", alog.Error("votePropRule ", "addr", a.fromaddr, "execaddr", a.execaddr, "checkVotesRecord failed",
voteProb.ProposalID, "err", err) voteProb.ProposalID, "err", err)
...@@ -175,13 +175,8 @@ func (a *action) votePropRule(voteProb *auty.VoteProposalRule) (*types.Receipt, ...@@ -175,13 +175,8 @@ func (a *action) votePropRule(voteProb *auty.VoteProposalRule) (*types.Receipt,
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kv []*types.KeyValue var kv []*types.KeyValue
if cur.VoteResult.TotalVotes != 0 && // 首次进入投票期,即将提案金转入自治系统地址
cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes != 0 && if cur.Status == auty.AutonomyStatusProposalRule {
float32(cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes) / float32(cur.VoteResult.TotalVotes) >= float32(pubAttendRatio)/100.0 &&
float32(cur.VoteResult.ApproveVotes) / float32(cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes) >= float32(pubApproveRatio)/100.0 {
cur.VoteResult.Pass = true
cur.PropRule.RealEndBlockHeight = a.height
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.Rule.ProposalAmount) receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.Rule.ProposalAmount)
if err != nil { if err != nil {
alog.Error("votePropRule ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err) alog.Error("votePropRule ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
...@@ -191,6 +186,14 @@ func (a *action) votePropRule(voteProb *auty.VoteProposalRule) (*types.Receipt, ...@@ -191,6 +186,14 @@ func (a *action) votePropRule(voteProb *auty.VoteProposalRule) (*types.Receipt,
kv = append(kv, receipt.KV...) kv = append(kv, receipt.KV...)
} }
if cur.VoteResult.TotalVotes != 0 &&
cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes != 0 &&
float32(cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes) / float32(cur.VoteResult.TotalVotes) >= float32(pubAttendRatio)/100.0 &&
float32(cur.VoteResult.ApproveVotes) / float32(cur.VoteResult.ApproveVotes + cur.VoteResult.OpposeVotes) >= float32(pubApproveRatio)/100.0 {
cur.VoteResult.Pass = true
cur.PropRule.RealEndBlockHeight = a.height
}
key := propRuleID(voteProb.ProposalID) key := propRuleID(voteProb.ProposalID)
cur.Status = auty.AutonomyStatusVotePropRule cur.Status = auty.AutonomyStatusVotePropRule
if cur.VoteResult.Pass { if cur.VoteResult.Pass {
...@@ -199,7 +202,7 @@ func (a *action) votePropRule(voteProb *auty.VoteProposalRule) (*types.Receipt, ...@@ -199,7 +202,7 @@ func (a *action) votePropRule(voteProb *auty.VoteProposalRule) (*types.Receipt,
kv = append(kv, &types.KeyValue{Key: key, Value: types.Encode(cur)}) kv = append(kv, &types.KeyValue{Key: key, Value: types.Encode(cur)})
// 更新VotesRecord // 更新VotesRecord
kv = append(kv, &types.KeyValue{Key: VotesRecord(voteProb.ProposalID), Value: types.Encode(votes)}) kv = append(kv, &types.KeyValue{Key: votesRecord(voteProb.ProposalID), Value: types.Encode(votes)})
// 更新系统规则 // 更新系统规则
if cur.VoteResult.Pass { if cur.VoteResult.Pass {
...@@ -228,7 +231,8 @@ func (a *action) tmintPropRule(tmintProb *auty.TerminateProposalRule) (*types.Re ...@@ -228,7 +231,8 @@ func (a *action) tmintPropRule(tmintProb *auty.TerminateProposalRule) (*types.Re
pre := copyAutonomyProposalRule(cur) pre := copyAutonomyProposalRule(cur)
// 检查当前状态 // 检查当前状态
if cur.Status == auty.AutonomyStatusTmintPropRule { if cur.Status == auty.AutonomyStatusTmintPropRule ||
cur.Status == auty.AutonomyStatusRvkPropRule {
err := auty.ErrProposalStatus err := auty.ErrProposalStatus
alog.Error("tmintPropRule ", "addr", a.fromaddr, "status", cur.Status, "status is not match", alog.Error("tmintPropRule ", "addr", a.fromaddr, "status", cur.Status, "status is not match",
tmintProb.ProposalID, "err", err) tmintProb.ProposalID, "err", err)
...@@ -263,6 +267,9 @@ func (a *action) tmintPropRule(tmintProb *auty.TerminateProposalRule) (*types.Re ...@@ -263,6 +267,9 @@ func (a *action) tmintPropRule(tmintProb *auty.TerminateProposalRule) (*types.Re
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kv []*types.KeyValue var kv []*types.KeyValue
// 未进行投票情况下,符合提案关闭的也需要扣除提案费用
if cur.Status == auty.AutonomyStatusProposalRule {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.Rule.ProposalAmount) receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyAddr, a.execaddr, cur.Rule.ProposalAmount)
if err != nil { if err != nil {
alog.Error("votePropRule ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err) alog.Error("votePropRule ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
...@@ -271,6 +278,8 @@ func (a *action) tmintPropRule(tmintProb *auty.TerminateProposalRule) (*types.Re ...@@ -271,6 +278,8 @@ func (a *action) tmintPropRule(tmintProb *auty.TerminateProposalRule) (*types.Re
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...) kv = append(kv, receipt.KV...)
}
cur.Status = auty.AutonomyStatusTmintPropRule cur.Status = auty.AutonomyStatusTmintPropRule
kv = append(kv, &types.KeyValue{Key: propRuleID(tmintProb.ProposalID), Value: types.Encode(cur)}) kv = append(kv, &types.KeyValue{Key: propRuleID(tmintProb.ProposalID), Value: types.Encode(cur)})
......
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