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

Merge pull request #611 from lyh169/autonomy_fund

Autonomy fund
parents a58294f8 21652d43
......@@ -211,6 +211,7 @@ ForkBase58AddressCheck=0
#平行链上使能平行链执行器如user.p.x.coins执行器的注册,缺省为0,对已有的平行链需要设置一个fork高度
ForkEnableParaRegExec=0
ForkCacheDriver=0
ForkTicketFundAddrV1=-1 #fork6.3
[fork.sub.coins]
Enable=0
......
......@@ -86,6 +86,7 @@ name="ticket"
minerstart=true
genesisBlockTime=1514533394
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
minerExecs=["ticket", "autonomy"]
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
......@@ -118,6 +119,9 @@ targetTimespan = 720
targetTimePerBlock = 5
ticketPrice = 3000
[mver.consensus.ForkTicketFundAddrV1]
fundKeyAddr = "1Ji3W12KGScCM7C2p8bg635sNkayDM8MGY"
[consensus.sub.ticket]
genesisBlockTime=1514533394
[[consensus.sub.ticket.genesis]]
......@@ -225,5 +229,4 @@ paraConsensusStopBlocks=30000
[exec.sub.autonomy]
total="16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
useBalance=false
useBalance=false
\ No newline at end of file
......@@ -3,7 +3,7 @@ module github.com/33cn/plugin
go 1.12
require (
github.com/33cn/chain33 v0.0.0-20190829065353-5e7a43bda97e
github.com/33cn/chain33 v0.0.0-20190906093700-93b043f5fce6
github.com/BurntSushi/toml v0.3.1
github.com/NebulousLabs/Sia v1.3.7
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac
......
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/33cn/chain33 v0.0.0-20190829065353-5e7a43bda97e h1:KUoBy94zIlsw96I/Mmb6/vZQnYZETBwWtfKqOgM2PLM=
github.com/33cn/chain33 v0.0.0-20190829065353-5e7a43bda97e/go.mod h1:4I8n+Zyf3t0UKM5jjpqJY627Tub62oXkLsdzIv4r6rQ=
github.com/33cn/chain33 v0.0.0-20190906093700-93b043f5fce6 h1:zj6rCGS9sowochmjveOoxhunvhqpkx1S6abhhhfS7KU=
github.com/33cn/chain33 v0.0.0-20190906093700-93b043f5fce6/go.mod h1:4I8n+Zyf3t0UKM5jjpqJY627Tub62oXkLsdzIv4r6rQ=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 h1:PqzgE6kAMi81xWQA2QIVxjWkFHptGgC547vchpUbtFo=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
......
......@@ -70,6 +70,7 @@ name="ticket"
minerstart=true
genesisBlockTime=1514533394
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
minerExecs=["ticket", "autonomy"]
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
......@@ -94,6 +95,9 @@ targetTimePerBlock = 2
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
[mver.consensus.ForkTicketFundAddrV1]
fundKeyAddr = "1Ji3W12KGScCM7C2p8bg635sNkayDM8MGY"
[consensus.sub.solo]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisBlockTime=1514533394
......@@ -173,3 +177,7 @@ superManager=[
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"
]
[exec.sub.autonomy]
total="16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
useBalance=false
\ No newline at end of file
......@@ -75,7 +75,7 @@ func AutonomyCmd() *cobra.Command {
// ProposalBoardCmd 创建提案命令
func ProposalBoardCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "proposalboard",
Use: "proposalBoard",
Short: "create proposal board",
Run: proposalBoard,
}
......@@ -87,6 +87,8 @@ func addProposalBoardFlags(cmd *cobra.Command) {
cmd.Flags().Int32P("year", "y", 0, "year")
cmd.Flags().Int32P("month", "m", 0, "month")
cmd.Flags().Int32P("day", "d", 0, "day")
cmd.Flags().BoolP("update", "u", false, "replace or update boards, default is replace(false); update(true)")
cmd.Flags().Int64P("startBlock", "s", 0, "start block height")
cmd.MarkFlagRequired("startBlock")
cmd.Flags().Int64P("endBlock", "e", 0, "end block height")
......@@ -102,6 +104,7 @@ func proposalBoard(cmd *cobra.Command, args []string) {
month, _ := cmd.Flags().GetInt32("month")
day, _ := cmd.Flags().GetInt32("day")
update, _ := cmd.Flags().GetBool("update")
startBlock, _ := cmd.Flags().GetInt64("startBlock")
endBlock, _ := cmd.Flags().GetInt64("endBlock")
boardstr, _ := cmd.Flags().GetString("boards")
......@@ -112,6 +115,7 @@ func proposalBoard(cmd *cobra.Command, args []string) {
Year: year,
Month: month,
Day: day,
Update: update,
Boards: boards,
StartBlockHeight: startBlock,
EndBlockHeight: endBlock,
......@@ -282,7 +286,7 @@ func addShowProposalBoardflags(cmd *cobra.Command) {
cmd.Flags().Uint32P("status", "s", 0, "status")
cmd.Flags().StringP("addr", "a", "", "address")
cmd.Flags().Int32P("count", "c", 1, "count, default is 1")
cmd.Flags().Int32P("direction", "d", -1, "direction, default is reserve")
cmd.Flags().Int32P("direction", "d", 0, "direction, default is reserve")
cmd.Flags().Int64P("height", "t", -1, "height, default is -1")
cmd.Flags().Int32P("index", "i", -1, "index, default is -1")
}
......
......@@ -19,7 +19,7 @@ import (
// ProposalChangeCmd 创建提案命令
func ProposalChangeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "proposalchange",
Use: "proposalChange",
Short: "create proposal change",
Run: proposalChange,
}
......@@ -238,7 +238,7 @@ func addShowProposalChangeflags(cmd *cobra.Command) {
cmd.Flags().Uint32P("status", "s", 0, "status")
cmd.Flags().StringP("addr", "a", "", "address")
cmd.Flags().Int32P("count", "c", 1, "count, default is 1")
cmd.Flags().Int32P("direction", "d", -1, "direction, default is reserve")
cmd.Flags().Int32P("direction", "d", 0, "direction, default is reserve")
cmd.Flags().Int64P("height", "t", -1, "height, default is -1")
cmd.Flags().Int32P("index", "i", -1, "index, default is -1")
}
......
......@@ -300,7 +300,7 @@ func addShowProposalProjectflags(cmd *cobra.Command) {
cmd.Flags().Uint32P("status", "s", 0, "status")
cmd.Flags().StringP("addr", "a", "", "address")
cmd.Flags().Int32P("count", "c", 1, "count, default is 1")
cmd.Flags().Int32P("direction", "d", -1, "direction, default is reserve")
cmd.Flags().Int32P("direction", "d", 0, "direction, default is reserve")
cmd.Flags().Int64P("height", "t", -1, "height, default is -1")
cmd.Flags().Int32P("index", "i", -1, "index, default is -1")
}
......
......@@ -37,7 +37,6 @@ func addProposalRuleFlags(cmd *cobra.Command) {
cmd.MarkFlagRequired("endBlock")
// 可修改规则
cmd.Flags().Int32P("boardAttendRatio", "t", 0, "board attend ratio(unit is %)")
cmd.Flags().Int32P("boardApproveRatio", "r", 0, "board approve ratio(unit is %)")
cmd.Flags().Int32P("pubOpposeRatio", "o", 0, "public oppose ratio(unit is %)")
cmd.Flags().Int64P("proposalAmount", "p", 0, "proposal cost amount")
......@@ -238,7 +237,7 @@ func addShowProposalRuleflags(cmd *cobra.Command) {
cmd.Flags().Uint32P("status", "s", 0, "status")
cmd.Flags().StringP("addr", "a", "", "address")
cmd.Flags().Int32P("count", "c", 1, "count, default is 1")
cmd.Flags().Int32P("direction", "d", -1, "direction, default is reserve")
cmd.Flags().Int32P("direction", "d", 0, "direction, default is reserve")
cmd.Flags().Int64P("height", "t", -1, "height, default is -1")
cmd.Flags().Int32P("index", "i", -1, "index, default is -1")
}
......@@ -403,7 +402,7 @@ func addShowProposalCommentflags(cmd *cobra.Command) {
cmd.Flags().StringP("proposalID", "p", "", "proposal ID")
cmd.MarkFlagRequired("proposalID")
cmd.Flags().Int32P("count", "c", 1, "count, default is 1")
cmd.Flags().Int32P("direction", "d", -1, "direction, default is reserve")
cmd.Flags().Int32P("direction", "d", 0, "direction, default is reserve")
cmd.Flags().Int64P("height", "t", -1, "height, default is -1")
cmd.Flags().Int64P("index", "i", -1, "index, default is -1")
}
......
......@@ -18,10 +18,10 @@ type subConfig struct {
}
var (
alog = log.New("module", "execs.autonomy")
driverName = auty.AutonomyX
autonomyFundAddr = address.ExecAddress("autonomyfund")
cfg subConfig
alog = log.New("module", "execs.autonomy")
driverName = auty.AutonomyX
autonomyAddr = address.ExecAddress(auty.AutonomyX)
cfg subConfig
)
func init() {
......
......@@ -52,16 +52,15 @@ func newAction(a *Autonomy, tx *types.Transaction, index int32) *action {
}
func (a *action) propBoard(prob *auty.ProposalBoard) (*types.Receipt, error) {
if len(prob.Boards) > maxBoards || len(prob.Boards) < minBoards {
alog.Error("propBoard ", "proposal boards number is invaild", len(prob.Boards))
return nil, types.ErrInvalidParam
}
if prob.StartBlockHeight < a.height || prob.EndBlockHeight < a.height ||
prob.StartBlockHeight+startEndBlockPeriod > prob.EndBlockHeight {
alog.Error("propBoard height invaild", "StartBlockHeight", prob.StartBlockHeight, "EndBlockHeight",
prob.EndBlockHeight, "height", a.height)
return nil, types.ErrInvalidParam
return nil, auty.ErrSetBlockHeight
}
if len(prob.Boards) == 0 {
alog.Error("propBoard ", "proposal boards number is zero", len(prob.Boards))
return nil, auty.ErrBoardNumber
}
mpBd := make(map[string]struct{})
......@@ -79,6 +78,40 @@ func (a *action) propBoard(prob *auty.ProposalBoard) (*types.Receipt, error) {
mpBd[board] = struct{}{}
}
var act *auty.ActiveBoard
var err error
if prob.Update {
act, err = a.getActiveBoard()
if err != nil {
alog.Error("propBoard ", "addr", a.fromaddr, "execaddr", a.execaddr, "getActiveBoard failed", err)
return nil, err
}
for _, board := range act.Boards {
if _, ok := mpBd[board]; ok {
err := auty.ErrRepeatAddr
alog.Error("propBoard ", "addr", board, "propBoard update have repeat addr in boards", err)
return nil, err
}
}
for _, board := range act.Revboards {
if _, ok := mpBd[board]; ok {
err := auty.ErrRepeatAddr
alog.Error("propBoard ", "addr", board, "propBoard update have repeat addr in revboards ", err)
return nil, err
}
}
act.Boards = append(act.Boards, prob.Boards...)
} else {
act = &auty.ActiveBoard{
Boards: prob.Boards,
}
}
if len(act.Boards) > maxBoards || len(act.Boards) < minBoards {
alog.Error("propBoard ", "proposal boards number is invaild", len(prob.Boards))
return nil, auty.ErrBoardNumber
}
// 获取当前生效提案规则
rule, err := a.getActiveRule()
if err != nil {
......@@ -101,6 +134,7 @@ func (a *action) propBoard(prob *auty.ProposalBoard) (*types.Receipt, error) {
cur := &auty.AutonomyProposalBoard{
PropBoard: prob,
CurRule: rule,
Board: act,
VoteResult: &auty.VoteResult{},
Status: auty.AutonomyStatusProposalBoard,
Address: a.fromaddr,
......@@ -257,7 +291,7 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt
// 首次进入投票期,即将提案金转入自治系统地址
if cur.Status == auty.AutonomyStatusProposalBoard {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyFundAddr, a.execaddr, cur.CurRule.ProposalAmount)
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, a.execaddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil {
alog.Error("votePropBoard ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
return nil, err
......@@ -286,11 +320,10 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt
// 更新当前具有权利的董事会成员
if cur.VoteResult.Pass {
act := &auty.ActiveBoard{
Boards: cur.PropBoard.Boards,
StartHeight: a.height,
if !cur.PropBoard.Update { // 非update才进行高度重写
cur.Board.StartHeight = a.height
}
kv = append(kv, &types.KeyValue{Key: activeBoardID(), Value: types.Encode(act)})
kv = append(kv, &types.KeyValue{Key: activeBoardID(), Value: types.Encode(cur.Board)})
}
ty := auty.TyLogVotePropBoard
......@@ -351,7 +384,7 @@ func (a *action) tmintPropBoard(tmintProb *auty.TerminateProposalBoard) (*types.
// 未进行投票情况下,符合提案关闭的也需要扣除提案费用
if cur.Status == auty.AutonomyStatusProposalBoard {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyFundAddr, a.execaddr, cur.CurRule.ProposalAmount)
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, a.execaddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil {
alog.Error("votePropBoard ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
return nil, err
......@@ -366,11 +399,10 @@ func (a *action) tmintPropBoard(tmintProb *auty.TerminateProposalBoard) (*types.
// 更新当前具有权利的董事会成员
if cur.VoteResult.Pass {
act := &auty.ActiveBoard{
Boards: cur.PropBoard.Boards,
StartHeight: a.height,
if !cur.PropBoard.Update { // 非update才进行高度重写
cur.Board.StartHeight = a.height
}
kv = append(kv, &types.KeyValue{Key: activeBoardID(), Value: types.Encode(act)})
kv = append(kv, &types.KeyValue{Key: activeBoardID(), Value: types.Encode(cur.Board)})
}
receiptLog := getReceiptLog(pre, cur, auty.TyLogTmintPropBoard)
......@@ -392,7 +424,8 @@ func (a *action) getTotalVotes(height int64) (int32, error) {
}
func (a *action) verifyMinerAddr(addrs []string, bindAddr string) (string, error) {
// 验证绑定关系
// 验证绑定关系与重复地址
mp := make(map[string]struct{})
for _, addr := range addrs {
value, err := a.db.Get(ticket.BindKey(addr))
if err != nil {
......@@ -403,6 +436,10 @@ func (a *action) verifyMinerAddr(addrs []string, bindAddr string) (string, error
if err != nil || tkBind.MinerAddress != bindAddr {
return addr, auty.ErrBindAddr
}
if _, ok := mp[addr]; ok {
return addr, auty.ErrRepeatAddr
}
mp[addr] = struct{}{}
}
return "", nil
}
......@@ -535,6 +572,14 @@ func copyAutonomyProposalBoard(cur *auty.AutonomyProposalBoard) *auty.AutonomyPr
newRule := *cur.GetCurRule()
newAut.CurRule = &newRule
}
if cur.Board != nil {
newBoard := *cur.GetBoard()
newBoard.Boards = make([]string, len(cur.Board.Boards))
copy(newBoard.Boards, cur.Board.Boards)
newBoard.Revboards = make([]string, len(cur.Board.Revboards))
copy(newBoard.Revboards, cur.Board.Revboards)
newAut.Board = &newBoard
}
if cur.VoteResult != nil {
newRes := *cur.GetVoteResult()
newAut.VoteResult = &newRes
......
......@@ -10,7 +10,6 @@ import (
"github.com/33cn/chain33/account"
apimock "github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/crypto"
dbm "github.com/33cn/chain33/common/db"
dbmock "github.com/33cn/chain33/common/db/mocks"
......@@ -157,7 +156,7 @@ func InitEnv() (*ExecEnv, drivers.Driver, dbm.KV, dbm.KVDB) {
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
accCoin.SaveAccount(&accountA)
accCoin.SaveExecAccount(address.ExecAddress(auty.AutonomyX), &accountA)
accCoin.SaveExecAccount(autonomyAddr, &accountA)
accCoin.SaveAccount(&accountB)
accCoin.SaveAccount(&accountC)
accCoin.SaveAccount(&accountD)
......@@ -183,6 +182,76 @@ func InitMinerAddr(stateDB dbm.KV, addrs []string, bind string) {
}
}
func TestPropBoard(t *testing.T) {
env, exec, stateDB, _ := InitEnv()
opts := []*auty.ProposalBoard{
{ // ErrRepeatAddr
Update: true,
Boards: []string{"18e1nfiux7aVSfN2zYUZhbidMRokbBSPA6", "18e1nfiux7aVSfN2zYUZhbidMRokbBSPA6"},
StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10,
},
{ // ErrRepeatAddr
Update: true,
Boards: []string{"18e1nfiux7aVSfN2zYUZhbidMRokbBSPA6", AddrA},
StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10,
},
{ // ErrBoardNumber
Update: true,
StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10,
},
{ // 正常
Update: true,
Boards: []string{"18e1nfiux7aVSfN2zYUZhbidMRokbBSPA6"},
StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10,
},
{ // ErrRepeatAddr
Update: false,
Boards: []string{"18e1nfiux7aVSfN2zYUZhbidMRokbBSPA6", "18e1nfiux7aVSfN2zYUZhbidMRokbBSPA6"},
StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10,
},
{ // ErrBoardNumber
Update: false,
Boards: []string{"18e1nfiux7aVSfN2zYUZhbidMRokbBSPA6", AddrA},
StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10,
},
{ // 正常
Update: false,
Boards: boards,
StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10,
},
}
result := []error{
auty.ErrRepeatAddr,
auty.ErrRepeatAddr,
auty.ErrBoardNumber,
nil,
auty.ErrRepeatAddr,
auty.ErrBoardNumber,
nil,
}
InitBoard(stateDB)
exec.SetStateDB(stateDB)
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
for i, tcase := range opts {
pbtx, err := propBoardTx(tcase)
assert.NoError(t, err)
pbtx, err = signTx(pbtx, PrivKeyA)
assert.NoError(t, err)
_, err = exec.Exec(pbtx, i)
assert.Equal(t, err, result[i])
}
}
func TestRevokeProposalBoard(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv()
// PropBoard
......@@ -251,7 +320,7 @@ func testPropBoard(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB dbm.
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, proposalAmount, account.Frozen)
}
......@@ -301,7 +370,7 @@ func revokeProposalBoard(t *testing.T, env *ExecEnv, exec drivers.Driver, stateD
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
}
......@@ -407,9 +476,9 @@ func voteProposalBoard(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB
// balance
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyFundAddr, address.ExecAddress(auty.AutonomyX))
account = accCoin.LoadExecAccount(autonomyAddr, autonomyAddr)
assert.Equal(t, proposalAmount, account.Balance)
// status
value, err := stateDB.Get(propBoardID(proposalID))
......@@ -484,7 +553,9 @@ func terminateProposalBoard(t *testing.T, env *ExecEnv, exec drivers.Driver, sta
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyAddr, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
}
......@@ -554,6 +625,7 @@ func TestCopyAutonomyProposalBoard(t *testing.T) {
assert.Nil(t, copyAutonomyProposalBoard(nil))
cur := &auty.AutonomyProposalBoard{
PropBoard: &auty.ProposalBoard{Year: 1900, Month: 1},
Board: &auty.ActiveBoard{Boards: []string{"111", "112"}, Revboards: []string{"113", "114"}},
CurRule: &auty.RuleConfig{BoardApproveRatio: 100},
VoteResult: &auty.VoteResult{TotalVotes: 100},
Status: 2,
......@@ -562,13 +634,16 @@ func TestCopyAutonomyProposalBoard(t *testing.T) {
pre := copyAutonomyProposalBoard(cur)
cur.PropBoard.Year = 1800
cur.PropBoard.Month = 2
cur.Board.Boards = []string{"211", "212"}
cur.Board.Revboards = []string{"113", "114"}
cur.CurRule.BoardApproveRatio = 90
cur.VoteResult.TotalVotes = 50
cur.Address = "234"
cur.Status = 1
assert.Equal(t, 1900, int(pre.PropBoard.Year))
assert.Equal(t, 1, int(pre.PropBoard.Month))
assert.Equal(t, []string{"111", "112"}, pre.Board.Boards)
assert.Equal(t, []string{"113", "114"}, pre.Board.Revboards)
assert.Equal(t, 100, int(pre.CurRule.BoardApproveRatio))
assert.Equal(t, 100, int(pre.VoteResult.TotalVotes))
assert.Equal(t, "123", pre.Address)
......@@ -596,6 +671,16 @@ func TestVerifyMinerAddr(t *testing.T) {
}
_, err := action.verifyMinerAddr(addrs, AddrD)
assert.NoError(t, err)
// ErrRepeatAddr
addrss := []string{
AddrA,
AddrB,
AddrC,
AddrA,
}
add, err := action.verifyMinerAddr(addrss, AddrD)
assert.Equal(t, auty.ErrRepeatAddr, err)
assert.Equal(t, add, AddrA)
// ErrMinerAddr
testf := "12HKLEn6g4FH39yUbHh4EVJWcFo5CXg22d"
......
......@@ -5,6 +5,8 @@
package executor
import (
"sort"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
......@@ -20,7 +22,7 @@ func (a *action) propChange(prob *auty.ProposalChange) (*types.Receipt, error) {
prob.StartBlockHeight+startEndBlockPeriod > prob.EndBlockHeight {
alog.Error("propChange height invaild", "StartBlockHeight", prob.StartBlockHeight, "EndBlockHeight",
prob.EndBlockHeight, "height", a.height)
return nil, types.ErrInvalidParam
return nil, auty.ErrSetBlockHeight
}
act, err := a.getActiveBoard()
......@@ -178,7 +180,7 @@ func (a *action) votePropChange(voteProb *auty.VoteProposalChange) (*types.Recei
// 首次进入投票期,即将提案金转入自治系统地址
if cur.Status == auty.AutonomyStatusProposalChange {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyFundAddr, a.execaddr, cur.CurRule.ProposalAmount)
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, a.execaddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil {
alog.Error("votePropChange ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
return nil, err
......@@ -238,7 +240,7 @@ func (a *action) tmintPropChange(tmintProb *auty.TerminateProposalChange) (*type
}
end := cur.GetPropChange().EndBlockHeight
if a.height < end && !cur.VoteResult.Pass {
if a.height <= end && !cur.VoteResult.Pass {
err := auty.ErrTerminatePeriod
alog.Error("tmintPropChange ", "addr", a.fromaddr, "status", cur.Status, "height", a.height,
"in vote period can not terminate", tmintProb.ProposalID, "err", err)
......@@ -258,7 +260,7 @@ func (a *action) tmintPropChange(tmintProb *auty.TerminateProposalChange) (*type
// 未进行投票情况下,符合提案关闭的也需要扣除提案费用
if cur.Status == auty.AutonomyStatusProposalChange {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyFundAddr, a.execaddr, cur.CurRule.ProposalAmount)
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, a.execaddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil {
alog.Error("votePropChange ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
return nil, err
......@@ -331,9 +333,11 @@ func (a *action) checkChangeable(act *auty.ActiveBoard, change []*auty.Change) (
for k := range mpBd {
new.Boards = append(new.Boards, k)
}
sort.Strings(new.Boards)
for k := range mpRbd {
new.Revboards = append(new.Revboards, k)
}
sort.Strings(new.Revboards)
return new, nil
}
......
......@@ -10,7 +10,6 @@ import (
"github.com/33cn/chain33/account"
apimock "github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
dbm "github.com/33cn/chain33/common/db"
_ "github.com/33cn/chain33/system"
drivers "github.com/33cn/chain33/system/dapp"
......@@ -99,7 +98,7 @@ func testPropChange(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB dbm
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, proposalAmount, account.Frozen)
}
......@@ -149,7 +148,7 @@ func revokeProposalChange(t *testing.T, env *ExecEnv, exec drivers.Driver, state
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
}
......@@ -262,9 +261,9 @@ func voteProposalChange(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB
// balance
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyFundAddr, address.ExecAddress(auty.AutonomyX))
account = accCoin.LoadExecAccount(autonomyAddr, autonomyAddr)
assert.Equal(t, proposalAmount, account.Balance)
// status
value, err := stateDB.Get(propChangeID(proposalID))
......@@ -347,7 +346,9 @@ func terminateProposalChange(t *testing.T, env *ExecEnv, exec drivers.Driver, st
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyAddr, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
}
......
......@@ -27,7 +27,7 @@ func (a *action) propProject(prob *auty.ProposalProject) (*types.Receipt, error)
prob.StartBlockHeight+startEndBlockPeriod > prob.EndBlockHeight {
alog.Error("propProject height or amount invaild", "StartBlockHeight", prob.StartBlockHeight, "EndBlockHeight",
prob.EndBlockHeight, "height", a.height, "amount", prob.Amount)
return nil, types.ErrInvalidParam
return nil, auty.ErrSetBlockHeight
}
// 获取董事会成员
......@@ -57,6 +57,14 @@ func (a *action) propProject(prob *auty.ProposalProject) (*types.Receipt, error)
return nil, err
}
// 判断基金中是否有足够资金
account := a.coinsAccount.LoadAccount(a.execaddr)
if account == nil || account.Balance < prob.Amount {
err = auty.ErrNotEnoughFund
alog.Error("propProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "the find have enough amount ", err)
return nil, err
}
var logs []*types.ReceiptLog
var kv []*types.KeyValue
......@@ -69,15 +77,6 @@ func (a *action) propProject(prob *auty.ProposalProject) (*types.Receipt, error)
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
// 冻结项目金
receiptPrj, err := a.coinsAccount.ExecFrozen(autonomyFundAddr, a.execaddr, prob.Amount)
if err != nil {
alog.Error("propProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecFrozen project amount", prob.Amount, "error", err)
return nil, err
}
logs = append(logs, receiptPrj.Logs...)
kv = append(kv, receiptPrj.KV...)
var isPubVote bool
if prob.Amount >= rule.LargeProjectAmount {
isPubVote = true
......@@ -148,15 +147,6 @@ func (a *action) rvkPropProject(rvkProb *auty.RevokeProposalProject) (*types.Rec
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
// 解冻项目金
receiptPrj, err := a.coinsAccount.ExecActive(autonomyFundAddr, a.execaddr, cur.PropProject.Amount)
if err != nil {
alog.Error("rvkPropProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecActive project amount", cur.PropProject.Amount, "error", err)
return nil, err
}
logs = append(logs, receiptPrj.Logs...)
kv = append(kv, receiptPrj.KV...)
cur.Status = auty.AutonomyStatusRvkPropProject
kv = append(kv, &types.KeyValue{Key: propProjectID(rvkProb.ProposalID), Value: types.Encode(cur)})
......@@ -233,7 +223,7 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
// 首次进入投票期,即将提案金转入自治系统地址
if cur.Status == auty.AutonomyStatusProposalProject {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyFundAddr, a.execaddr, cur.CurRule.ProposalAmount)
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, a.execaddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil {
alog.Error("votePropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
return nil, err
......@@ -258,11 +248,12 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
} else {
cur.Status = auty.AutonomyStatusTmintPropProject
// 提案通过,将工程金额从基金付款给承包商
receipt, err := a.coinsAccount.ExecTransferFrozen(autonomyFundAddr, cur.PropProject.ToAddr, a.execaddr, cur.PropProject.Amount)
receipt, err := a.coinsAccount.ExecDeposit(cur.PropProject.ToAddr, a.execaddr, cur.PropProject.Amount)
if err != nil {
alog.Error("votePropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen to contractor project amount fail", err)
alog.Error("votePropProject ", "addr", cur.PropProject.ToAddr, "execaddr", a.execaddr, "Transfer to contractor project amount fail", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
// 需要更新该董事会的累计审批金
......@@ -379,14 +370,6 @@ func (a *action) pubVotePropProject(voteProb *auty.PubVoteProposalProject) (*typ
cur.PubVote.PubPass = false
cur.PropProject.RealEndBlockHeight = a.height
// 解冻项目金
receiptPrj, err := a.coinsAccount.ExecActive(autonomyFundAddr, a.execaddr, cur.PropProject.Amount)
if err != nil {
alog.Error("pubVotePropProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecActive project amount", cur.PropProject.Amount, "error", err)
return nil, err
}
logs = append(logs, receiptPrj.Logs...)
kv = append(kv, receiptPrj.KV...)
}
key := propProjectID(voteProb.ProposalID)
......@@ -472,7 +455,7 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty
// 如果为提案状态,则判断是否需要扣除提案费
if cur.Status == auty.AutonomyStatusProposalProject && a.height > end {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyFundAddr, a.execaddr, cur.CurRule.ProposalAmount)
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, a.execaddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil {
alog.Error("tmintPropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
return nil, err
......@@ -484,11 +467,12 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty
if (cur.PubVote.Publicity && cur.PubVote.PubPass) || // 需要公示且公示通过
(!cur.PubVote.Publicity && cur.BoardVoteRes.Pass) { // 不需要公示且董事会通过
// 提案通过,将工程金额从基金付款给承包商
receipt, err := a.coinsAccount.ExecTransferFrozen(autonomyFundAddr, cur.PropProject.ToAddr, a.execaddr, cur.PropProject.Amount)
receipt, err := a.coinsAccount.ExecDeposit(cur.PropProject.ToAddr, a.execaddr, cur.PropProject.Amount)
if err != nil {
alog.Error("tmintPropProject ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen to contractor project amount fail", err)
alog.Error("tmintPropProject ", "addr", cur.PropProject.ToAddr, "execaddr", a.execaddr, "Transfer to contractor project amount fail", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
// 需要更新该董事会的累计审批金
......@@ -498,15 +482,6 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty
return nil, err
}
kv = append(kv, pakv)
} else {
// 解冻项目金
receiptPrj, err := a.coinsAccount.ExecActive(autonomyFundAddr, a.execaddr, cur.PropProject.Amount)
if err != nil {
alog.Error("tmintPropProject ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecActive project amount", cur.PropProject.Amount, "error", err)
return nil, err
}
logs = append(logs, receiptPrj.Logs...)
kv = append(kv, receiptPrj.KV...)
}
cur.Status = auty.AutonomyStatusTmintPropProject
......@@ -572,6 +547,10 @@ func copyAutonomyProposalProject(cur *auty.AutonomyProposalProject) *auty.Autono
newRule := *cur.GetCurRule()
newAut.CurRule = &newRule
}
if len(cur.Boards) > 0 {
newAut.Boards = make([]string, len(cur.Boards))
copy(newAut.Boards, cur.Boards)
}
if cur.BoardVoteRes != nil {
newRes := *cur.GetBoardVoteRes()
newAut.BoardVoteRes = &newRes
......
......@@ -10,7 +10,6 @@ import (
"github.com/33cn/chain33/account"
apimock "github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
dbm "github.com/33cn/chain33/common/db"
_ "github.com/33cn/chain33/system"
drivers "github.com/33cn/chain33/system/dapp"
......@@ -20,18 +19,9 @@ import (
"github.com/stretchr/testify/mock"
)
//const (
// testBoardAttendRatio int32 = 60
// testBoardApproveRatio int32 = 60
// testPubOpposeRatio int32 = 30
// testProposalAmount int64 = 0
// testLargeProjectAmount int64 = 1
//)
var autonomyAddr = address.ExecAddress(auty.AutonomyX)
const (
testProjectAmount int64 = types.Coin * 100 // 工程需要资金
testProjectAmount int64 = types.Coin * 100 // 工程需要资金
testFundAmount int64 = types.Coin * 1000 // 工程需要资金
)
func InitBoard(stateDB dbm.KV) {
......@@ -58,11 +48,12 @@ func InitFund(stateDB dbm.KV, amount int64) {
accountA := types.Account{
Balance: amount,
Frozen: 0,
Addr: autonomyFundAddr,
Addr: autonomyAddr,
}
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
accCoin.SaveExecAccount(autonomyAddr, &accountA)
//accCoin.ExecIssueCoins(autonomyAddr, amount)
accCoin.SaveAccount(&accountA)
}
func TestPropProject(t *testing.T) {
......@@ -102,8 +93,8 @@ func TestPropProject(t *testing.T) {
result := []error{
types.ErrInvalidAddress,
types.ErrInvalidParam,
types.ErrInvalidParam,
auty.ErrSetBlockHeight,
auty.ErrSetBlockHeight,
types.ErrNotFound,
auty.ErrNoPeriodAmount,
}
......@@ -131,7 +122,7 @@ func TestPropProject(t *testing.T) {
func TestRevokeProposalProject(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv()
InitBoard(stateDB)
InitFund(stateDB, testProjectAmount)
InitFund(stateDB, testFundAmount)
// PropProject
testPropProject(t, env, exec, stateDB, kvdb, true)
//RevokeProposalProject
......@@ -141,7 +132,7 @@ func TestRevokeProposalProject(t *testing.T) {
func TestVoteProposalProject(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv()
InitBoard(stateDB)
InitFund(stateDB, testProjectAmount)
InitFund(stateDB, testFundAmount)
// PropProject
testPropProject(t, env, exec, stateDB, kvdb, true)
//voteProposalProject
......@@ -154,7 +145,7 @@ func TestPubVoteProposalProject(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv()
InitBoard(stateDB)
InitRule(stateDB)
InitFund(stateDB, testProjectAmount)
InitFund(stateDB, testFundAmount)
// PropProject
testPropProject(t, env, exec, stateDB, kvdb, true)
// voteProposalProject
......@@ -169,7 +160,7 @@ func TestPubVoteProposalProject(t *testing.T) {
func TestTerminateProposalProject(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv()
InitBoard(stateDB)
InitFund(stateDB, testProjectAmount)
InitFund(stateDB, testFundAmount)
// PropProject
testPropProject(t, env, exec, stateDB, kvdb, true)
//terminateProposalProject
......@@ -262,7 +253,7 @@ func testPropProject(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB db
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, proposalAmount, account.Frozen)
}
......@@ -313,7 +304,7 @@ func revokeProposalProject(t *testing.T, env *ExecEnv, exec drivers.Driver, stat
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
// check Project
au := &Autonomy{
......@@ -443,13 +434,6 @@ func voteProposalProjectTx(parm *auty.VoteProposalProject) (*types.Transaction,
func checkVoteProposalProjectResult(t *testing.T, stateDB dbm.KV, proposalID string) {
// check
// balance
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
assert.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyFundAddr, address.ExecAddress(auty.AutonomyX))
assert.Equal(t, proposalAmount, account.Balance)
// status
value, err := stateDB.Get(propProjectID(proposalID))
assert.NoError(t, err)
......@@ -458,7 +442,15 @@ func checkVoteProposalProjectResult(t *testing.T, stateDB dbm.KV, proposalID str
assert.NoError(t, err)
assert.Equal(t, int32(auty.AutonomyStatusTmintPropProject), cur.Status)
assert.Equal(t, AddrA, cur.Address)
// balance
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyAddr, autonomyAddr)
assert.Equal(t, proposalAmount, account.Balance)
account = accCoin.LoadExecAccount(AddrD, autonomyAddr)
assert.Equal(t, testProjectAmount, account.Balance)
// 更新董事会累计审批金
value, err = stateDB.Get(activeBoardID())
assert.NoError(t, err)
......@@ -559,13 +551,6 @@ func pubVoteProposalProject(t *testing.T, env *ExecEnv, exec drivers.Driver, sta
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))
assert.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyFundAddr, address.ExecAddress(auty.AutonomyX))
assert.Equal(t, proposalAmount+testProjectAmount, account.Balance)
// status
value, err := stateDB.Get(propProjectID(proposalID))
assert.NoError(t, err)
......@@ -574,6 +559,15 @@ func checkPubVoteProposalProjectResult(t *testing.T, stateDB dbm.KV, proposalID
assert.NoError(t, err)
assert.Equal(t, int32(auty.AutonomyStatusTmintPropProject), cur.Status)
assert.Equal(t, AddrA, cur.Address)
// balance
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(AddrD, autonomyAddr)
assert.Equal(t, int64(0), account.Balance)
account = accCoin.LoadExecAccount(autonomyAddr, autonomyAddr)
assert.Equal(t, proposalAmount, account.Balance)
// 更新董事会累计审批金
value, err = stateDB.Get(activeBoardID())
......@@ -646,7 +640,7 @@ func terminateProposalProject(t *testing.T, env *ExecEnv, exec drivers.Driver, s
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
// check Project
......
......@@ -56,7 +56,7 @@ func (a *action) propRule(prob *auty.ProposalRule) (*types.Receipt, error) {
prob.StartBlockHeight+startEndBlockPeriod > prob.EndBlockHeight {
alog.Error("propRule height invaild", "StartBlockHeight", prob.StartBlockHeight, "EndBlockHeight",
prob.EndBlockHeight, "height", a.height)
return nil, types.ErrInvalidParam
return nil, auty.ErrSetBlockHeight
}
// 获取当前生效提案规则,并且将不修改的规则补齐
......@@ -240,7 +240,7 @@ func (a *action) votePropRule(voteProb *auty.VoteProposalRule) (*types.Receipt,
// 首次进入投票期,即将提案金转入自治系统地址
if cur.Status == auty.AutonomyStatusProposalRule {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyFundAddr, a.execaddr, cur.CurRule.ProposalAmount)
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, a.execaddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil {
alog.Error("votePropRule ", "addr", cur.Address, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
return nil, err
......@@ -304,7 +304,7 @@ func (a *action) tmintPropRule(tmintProb *auty.TerminateProposalRule) (*types.Re
start := cur.GetPropRule().StartBlockHeight
end := cur.GetPropRule().EndBlockHeight
if a.height < end && !cur.VoteResult.Pass {
if a.height <= end && !cur.VoteResult.Pass {
err := auty.ErrTerminatePeriod
alog.Error("tmintPropRule ", "addr", a.fromaddr, "status", cur.Status, "height", a.height,
"in vote period can not terminate", tmintProb.ProposalID, "err", err)
......@@ -332,7 +332,7 @@ func (a *action) tmintPropRule(tmintProb *auty.TerminateProposalRule) (*types.Re
// 未进行投票情况下,符合提案关闭的也需要扣除提案费用
if cur.Status == auty.AutonomyStatusProposalRule {
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, autonomyFundAddr, a.execaddr, cur.CurRule.ProposalAmount)
receipt, err := a.coinsAccount.ExecTransferFrozen(cur.Address, a.execaddr, a.execaddr, cur.CurRule.ProposalAmount)
if err != nil {
alog.Error("votePropRule ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecTransferFrozen amount fail", err)
return nil, err
......@@ -366,7 +366,7 @@ func (a *action) transfer(tf *auty.TransferFund) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
receipt, err := a.coinsAccount.ExecTransfer(a.fromaddr, autonomyFundAddr, a.execaddr, tf.Amount)
receipt, err := a.coinsAccount.ExecTransfer(a.fromaddr, autonomyAddr, autonomyAddr, tf.Amount)
if err != nil {
alog.Error("autonomy transfer ", "addr", a.fromaddr, "amount", tf.Amount, "ExecTransfer fail", err)
return nil, err
......
......@@ -10,7 +10,6 @@ import (
"github.com/33cn/chain33/account"
apimock "github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
dbm "github.com/33cn/chain33/common/db"
_ "github.com/33cn/chain33/system"
drivers "github.com/33cn/chain33/system/dapp"
......@@ -186,7 +185,7 @@ func testPropRule(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB dbm.K
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, proposalAmount, account.Frozen)
}
......@@ -236,7 +235,7 @@ func revokeProposalRule(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
// check rule
au := &Autonomy{
......@@ -356,9 +355,9 @@ func voteProposalRule(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB d
// balance
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyFundAddr, address.ExecAddress(auty.AutonomyX))
account = accCoin.LoadExecAccount(autonomyAddr, autonomyAddr)
assert.Equal(t, proposalAmount, account.Balance)
// status
value, err := stateDB.Get(propRuleID(proposalID))
......@@ -447,8 +446,10 @@ func terminateProposalRule(t *testing.T, env *ExecEnv, exec drivers.Driver, stat
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, int64(0), account.Frozen)
account = accCoin.LoadExecAccount(autonomyAddr, autonomyAddr)
assert.Equal(t, proposalAmount, account.Balance)
// check rule
au := &Autonomy{
......@@ -589,9 +590,9 @@ func TestTransfer(t *testing.T) {
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
account := accCoin.LoadExecAccount(AddrA, autonomyAddr)
assert.Equal(t, total-types.Coin*190, account.Balance)
account = accCoin.LoadExecAccount(autonomyFundAddr, address.ExecAddress(auty.AutonomyX))
account = accCoin.LoadExecAccount(autonomyAddr, autonomyAddr)
assert.Equal(t, types.Coin*190, account.Balance)
}
......
......@@ -13,14 +13,16 @@ message AutonomyProposalBoard {
ProposalBoard propBoard = 1;
// 投票该提案的规则
RuleConfig curRule = 2;
// 投票董事会
ActiveBoard board = 3;
// 全体持票人投票结果
VoteResult voteResult = 3;
VoteResult voteResult = 4;
// 状态
int32 status = 4;
string address = 5;
int64 height = 6;
int32 index = 7;
string proposalID = 8;
int32 status = 5;
string address = 6;
int64 height = 7;
int32 index = 8;
string proposalID = 9;
}
// action
......@@ -30,13 +32,15 @@ message ProposalBoard {
int32 month = 2;
int32 day = 3;
// 是否更新
bool update = 4;
// 提案董事会成员
repeated string boards = 4;
repeated string boards = 5;
// 投票相关
int64 startBlockHeight = 5; // 提案开始投票高度
int64 endBlockHeight = 6; // 提案结束投票高度
int64 realEndBlockHeight = 7; // 实际提案结束投票高度
int64 startBlockHeight = 6; // 提案开始投票高度
int64 endBlockHeight = 7; // 提案结束投票高度
int64 realEndBlockHeight = 8; // 实际提案结束投票高度
}
message RevokeProposalBoard {
......
......@@ -33,7 +33,7 @@ message ProposalChange {
int32 day = 3;
// 修改董事会成员
repeated Change Changes = 4;
repeated Change changes = 4;
// 投票相关
int64 startBlockHeight = 5; // 提案开始投票高度
......
This diff is collapsed.
This diff is collapsed.
......@@ -35,4 +35,8 @@ var (
ErrBoardNumber = errors.New("ErrBoardNumber")
// ErrRepeatAddr 重复地址
ErrRepeatAddr = errors.New("ErrRepeatAddr")
// ErrNotEnoughFund 重复地址
ErrNotEnoughFund = errors.New("ErrNotEnoughFund")
// ErrSetBlockHeight block height not match
ErrSetBlockHeight = errors.New("ErrSetBlockHeight")
)
......@@ -70,6 +70,7 @@ name="ticket"
minerstart=true
genesisBlockTime=1514533394
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
minerExecs=["ticket", "autonomy"]
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
......@@ -100,6 +101,9 @@ targetTimespan = 720
targetTimePerBlock = 1
powLimitBits = "0x1f2fffff"
[mver.consensus.ForkTicketFundAddrV1]
fundKeyAddr = "1Ji3W12KGScCM7C2p8bg635sNkayDM8MGY"
[consensus.sub.solo]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisBlockTime=1514533394
......@@ -180,6 +184,10 @@ superManager=[
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"
]
[exec.sub.autonomy]
total="16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
useBalance=false
#系统中所有的fork,默认用chain33的测试网络的
#但是我们可以替换
[fork.system]
......@@ -204,6 +212,7 @@ ForkBlockCheck=-1 #fork 6.2
ForkBase58AddressCheck=-1 #fork6.2
ForkEnableParaRegExec=0
ForkCacheDriver=0
ForkTicketFundAddrV1=-1 #fork6.3
[fork.sub.coins]
Enable=0
[fork.sub.ticket]
......
......@@ -340,11 +340,23 @@ func (action *Action) TicketMiner(miner *ty.TicketMiner, index int) (*types.Rece
return nil, err
}
//fund
receipt2, err := action.coinsAccount.ExecDepositFrozen(types.GetFundAddr(), action.execaddr, cfg.CoinDevFund)
if err != nil {
tlog.Error("TicketMiner.ExecDepositFrozen fund", "addr", types.GetFundAddr(), "execaddr", action.execaddr)
return nil, err
var receipt2 *types.Receipt
if types.IsFork(action.height, "ForkTicketFundAddrV1") {
// issue coins to exec addr
addr := types.MGStr("mver.consensus.fundKeyAddr", action.height)
receipt2, err = action.coinsAccount.ExecIssueCoins(addr, cfg.CoinDevFund)
if err != nil {
tlog.Error("TicketMiner.ExecDepositFrozen fund to autonomy fund", "addr", addr, "error", err)
return nil, err
}
} else {
receipt2, err = action.coinsAccount.ExecDepositFrozen(types.GetFundAddr(), action.execaddr, cfg.CoinDevFund)
if err != nil {
tlog.Error("TicketMiner.ExecDepositFrozen fund", "addr", types.GetFundAddr(), "execaddr", action.execaddr, "error", err)
return nil, err
}
}
t.Save(action.db)
logs = append(logs, t.GetReceiptLog())
kv = append(kv, t.GetKVSet()...)
......@@ -409,13 +421,15 @@ func (action *Action) TicketClose(tclose *ty.TicketClose) (*types.Receipt, error
kv = append(kv, receipt1.KV...)
//如果ticket 已经挖矿成功了,那么要解冻发展基金部分币
if t.prevstatus == 2 {
receipt2, err := action.coinsAccount.ExecActive(types.GetFundAddr(), action.execaddr, cfg.CoinDevFund)
if err != nil {
tlog.Error("TicketClose.ExecActive fund", "addr", types.GetFundAddr(), "execaddr", action.execaddr, "value", retValue)
return nil, err
if !types.IsFork(action.height, "ForkTicketFundAddrV1") {
receipt2, err := action.coinsAccount.ExecActive(types.GetFundAddr(), action.execaddr, cfg.CoinDevFund)
if err != nil {
tlog.Error("TicketClose.ExecActive fund", "addr", types.GetFundAddr(), "execaddr", action.execaddr, "value", retValue)
return nil, err
}
logs = append(logs, receipt2.Logs...)
kv = append(kv, receipt2.KV...)
}
logs = append(logs, receipt2.Logs...)
kv = append(kv, receipt2.KV...)
}
t.Save(action.db)
}
......
......@@ -17,12 +17,18 @@ import (
"github.com/stretchr/testify/assert"
)
func TestJRPCChannel(t *testing.T) {
// 启动RPCmocker
mocker := testnode.New("--notset--", nil)
defer mocker.Close()
var mocker *testnode.Chain33Mock
func TestMain(m *testing.M) {
cfg, sub := testnode.GetDefaultConfig()
cfg.Consensus.Name = "ticket"
mocker = testnode.NewWithConfig(cfg, sub, nil)
mocker.Listen()
m.Run()
mocker.Close()
}
func TestJRPCChannel(t *testing.T) {
jrpcClient := mocker.GetJSONC()
testCases := []struct {
......
......@@ -10,22 +10,15 @@ import (
rpctypes "github.com/33cn/chain33/rpc/types"
_ "github.com/33cn/chain33/system"
"github.com/33cn/chain33/util/testnode"
_ "github.com/33cn/plugin/plugin"
ty "github.com/33cn/plugin/plugin/dapp/ticket/types"
"github.com/stretchr/testify/assert"
)
func TestNewTicket(t *testing.T) {
cfg, sub := testnode.GetDefaultConfig()
cfg.Consensus.Name = "ticket"
mock33 := testnode.NewWithConfig(cfg, sub, nil)
defer mock33.Close()
mock33.WaitHeight(5)
mock33.Listen()
//选票(可以用hotwallet 关闭选票)
in := &ty.TicketClose{MinerAddress: mock33.GetHotAddress()}
in := &ty.TicketClose{MinerAddress: mocker.GetHotAddress()}
var res rpctypes.ReplyHashes
err := mock33.GetJSONC().Call("ticket.CloseTickets", in, &res)
err := mocker.GetJSONC().Call("ticket.CloseTickets", in, &res)
assert.Nil(t, err)
}
......@@ -46,7 +46,7 @@ func (t *token) Exec_TokenPreCreate(payload *tokenty.TokenPreCreate, tx *types.T
}
func (t *token) Exec_TokenFinishCreate(payload *tokenty.TokenFinishCreate, tx *types.Transaction, index int) (*types.Receipt, error) {
action := newTokenAction(t, types.GetFundAddr(), tx)
action := newTokenAction(t, types.MGStr("mver.consensus.fundKeyAddr", t.GetHeight()), tx)
return action.finishCreate(payload)
}
......
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