Commit 9771febb authored by liuyuhang's avatar liuyuhang

add change test

parent 05b8ae47
......@@ -117,9 +117,9 @@ type RoundState struct {
// RoundStateMessage ...
func (rs *RoundState) RoundStateMessage() *tmtypes.NewRoundStepMsg {
return &tmtypes.NewRoundStepMsg{
Height: rs.Height,
Round: int32(rs.Round),
Step: int32(rs.Step),
Height: rs.Height,
Round: int32(rs.Round),
Step: int32(rs.Step),
SecondsSinceStartTime: int32(time.Since(rs.StartTime).Seconds()),
LastCommitRound: int32(rs.LastCommit.Round()),
}
......
......@@ -58,14 +58,14 @@ func proposalChange(cmd *cobra.Command, args []string) {
if len(per) == 2 {
if per[1] == "true" {
change := &auty.Change{
Cancel:true,
Addr:per[0],
Cancel: true,
Addr: per[0],
}
changes = append(changes, change)
} else if per[1] == "false" {
change := &auty.Change{
Cancel:false,
Addr:per[0],
Cancel: false,
Addr: per[0],
}
changes = append(changes, change)
}
......@@ -75,7 +75,7 @@ func proposalChange(cmd *cobra.Command, args []string) {
Year: year,
Month: month,
Day: day,
Changes: changes,
Changes: changes,
StartBlockHeight: startBlock,
EndBlockHeight: endBlock,
}
......
......@@ -7,12 +7,13 @@ package commands
import (
"encoding/json"
"strings"
jsonrpc "github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
"github.com/spf13/cobra"
"strings"
)
// ProposalProjectCmd 创建提案命令
......
......@@ -7,12 +7,13 @@ package commands
import (
"encoding/json"
"strings"
jsonrpc "github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
"github.com/spf13/cobra"
"strings"
)
// ProposalRuleCmd 创建提案命令
......
......@@ -285,7 +285,7 @@ func (a *action) votePropBoard(voteProb *auty.VoteProposalBoard) (*types.Receipt
// 更新当前具有权利的董事会成员
if cur.VoteResult.Pass {
act := &auty.ActiveBoard{
Boards: cur.PropBoard.Boards,
Boards: cur.PropBoard.Boards,
StartHeight: a.height,
}
kv = append(kv, &types.KeyValue{Key: activeBoardID(), Value: types.Encode(act)})
......@@ -365,7 +365,7 @@ func (a *action) tmintPropBoard(tmintProb *auty.TerminateProposalBoard) (*types.
// 更新当前具有权利的董事会成员
if cur.VoteResult.Pass {
act := &auty.ActiveBoard{
Boards: cur.PropBoard.Boards,
Boards: cur.PropBoard.Boards,
StartHeight: a.height,
}
kv = append(kv, &types.KeyValue{Key: activeBoardID(), Value: types.Encode(act)})
......@@ -398,7 +398,7 @@ func (a *action) verifyMinerAddr(addrs []string, bindAddr string) (string, error
}
tkBind := &ticketTy.TicketBind{}
err = types.Decode(value, tkBind)
if err != nil ||tkBind.MinerAddress != bindAddr {
if err != nil || tkBind.MinerAddress != bindAddr {
return addr, auty.ErrBindAddr
}
}
......@@ -503,7 +503,7 @@ func (a *action) checkVotesRecord(addrs []string, key []byte) (*auty.VotesRecord
for _, addr := range votes.Address {
if _, ok := mp[addr]; ok {
err := auty.ErrRepeatVoteAddr
alog.Error("autonomy ", "addr", addr, "err", err)
alog.Error("autonomy ", "addr", addr, "err", err)
return nil, err
}
}
......
......@@ -20,10 +20,10 @@ import (
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
ticket "github.com/33cn/plugin/plugin/dapp/ticket/executor"
ticketTy "github.com/33cn/plugin/plugin/dapp/ticket/types"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
ticketTy "github.com/33cn/plugin/plugin/dapp/ticket/types"
ticket "github.com/33cn/plugin/plugin/dapp/ticket/executor"
)
// ExecEnv exec environment
......@@ -47,43 +47,70 @@ var (
AddrC = "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
AddrD = "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
PrivKey1 = "0x9d4f8ab11361be596468b265cb66946c87873d4a119713fd0c3d8302eae0a8e4"
PrivKey2 = "0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5"
PrivKey3 = "0xc21d38be90493512a5c2417d565269a8b23ce8152010e404ff4f75efead8183a"
PrivKey4 = "0xfdf2bbff853ecff2e7b86b2a8b45726c6538ca7d1403dc94e50131ef379bdca0"
PrivKey5 = "0x794443611e7369a57b078881445b93b754cbc9b9b8f526535ab9c6d21d29203d"
PrivKey6 = "0xf2cc48d30560e4c92e84821df68cf1086de82ee6a5725fc2a590a58d6ffe4fc5"
PrivKey7 = "0xeb4738a7c685a7ccf5471c3335a2d7ebe284b11d8a1717d814904b8d1ba936d9"
PrivKey8 = "0x9d315182e56fde7fadb94408d360203894e5134216944e858f9b31f70e9ecf40"
PrivKey9 = "0x128de4afa7c061c00d854a1bca51b58e80a2c292583739e5aebf4c0f778959e1"
PrivKey1 = "0x9d4f8ab11361be596468b265cb66946c87873d4a119713fd0c3d8302eae0a8e4"
PrivKey2 = "0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5"
PrivKey3 = "0xc21d38be90493512a5c2417d565269a8b23ce8152010e404ff4f75efead8183a"
PrivKey4 = "0xfdf2bbff853ecff2e7b86b2a8b45726c6538ca7d1403dc94e50131ef379bdca0"
PrivKey5 = "0x794443611e7369a57b078881445b93b754cbc9b9b8f526535ab9c6d21d29203d"
PrivKey6 = "0xf2cc48d30560e4c92e84821df68cf1086de82ee6a5725fc2a590a58d6ffe4fc5"
PrivKey7 = "0xeb4738a7c685a7ccf5471c3335a2d7ebe284b11d8a1717d814904b8d1ba936d9"
PrivKey8 = "0x9d315182e56fde7fadb94408d360203894e5134216944e858f9b31f70e9ecf40"
PrivKey9 = "0x128de4afa7c061c00d854a1bca51b58e80a2c292583739e5aebf4c0f778959e1"
PrivKey10 = "0x1c3e6cac2f887e1ab9180e2d5772dc4ba01accb8d4df434faba097003eb35482"
Addr1 = "12HKLEn6g4FH39yUbHh4EVJWcFo5CXg22d"
Addr2 = "1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj"
Addr3 = "12cjnN5D4DPdBQSwh6vjwJbtsW4EJALTMv"
Addr4 = "1Luh4AziYyaC5zP3hUXtXFZS873xAxm6rH"
Addr5 = "1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB"
Addr6 = "1L1puAUjfmtDECKo2C1qLWsAMZtDGTBWf6"
Addr7 = "1LNf9AVXzUMQkQM5hgGLhkdrVtD8UMBSUm"
Addr8 = "1PcGKYYoLn1PLLJJodc1UpgWGeFAQasAkx"
Addr9 = "1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu"
Addr10 = "1Q9sQwothzM1gKSzkVZ8Dt1tqKX1uzSagx"
PrivKey11 = "0xfd0c4a8a1efcd221ee0f36b7d4f57d8ff843cb8bc193b39c7863332d355acafa"
PrivKey12 = "0x4c9691bf6acc908ef5c07abcad23cf7f98e46e84101aa5059322aa53eb4dc471"
PrivKey13 = "0x50b9c6a4358ef8ffc96d5831a8dfd5e0fae504d49e20c5eafd12b6015423de33"
PrivKey14 = "0x96e3c766850a915fe4718b890d96208d5d1a3694b2597e08165480b5b48b84cb"
PrivKey15 = "0xeac5e45243c3920cf8a98f3d3a2e3a9b43f30a21769b57f734213913511e7575"
PrivKey16 = "0xd2aaa6f050a4db13fbd2c8bf87cbb96e217289172baca6c12e8a8b0680b9aa1a"
PrivKey17 = "0x33b3b977c657435a49773b5605a704ad5fdca0fa34fe36a02ea0f13a49099832"
Addr11 = "15VUiygdxMSZ3rykwe742yomp2cPJ9Tfve"
Addr12 = "1DyR84CU5AHbGXLEnhHMwMvWNMeunLZsuJ"
Addr13 = "132pBvrgSYgHASxzoeL3bqnsqUpaBbUktm"
Addr14 = "1DEV4XwdBUWRkMuy4ARRiEAoxQ2LoDByNG"
Addr15 = "18Y87cw2hiYC71bvpD872oYMYXtw66Qp6o"
Addr16 = "1Fghq6cgdJEDr6gQBmvba3t6aXAkyZyjr2"
Addr17 = "142KsfJLvEA5FJxAgKm9ZDtFVjkRaPdu82"
boards = []string{
AddrA,
AddrB,
AddrC,
AddrD,
"12HKLEn6g4FH39yUbHh4EVJWcFo5CXg22d",
"1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj",
"12cjnN5D4DPdBQSwh6vjwJbtsW4EJALTMv",
"1Luh4AziYyaC5zP3hUXtXFZS873xAxm6rH",
"1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB",
"1L1puAUjfmtDECKo2C1qLWsAMZtDGTBWf6",
"1LNf9AVXzUMQkQM5hgGLhkdrVtD8UMBSUm",
"1PcGKYYoLn1PLLJJodc1UpgWGeFAQasAkx",
"1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu",
"1Q9sQwothzM1gKSzkVZ8Dt1tqKX1uzSagx",
"15VUiygdxMSZ3rykwe742yomp2cPJ9Tfve",
"1DyR84CU5AHbGXLEnhHMwMvWNMeunLZsuJ",
"132pBvrgSYgHASxzoeL3bqnsqUpaBbUktm",
"1DEV4XwdBUWRkMuy4ARRiEAoxQ2LoDByNG",
"18Y87cw2hiYC71bvpD872oYMYXtw66Qp6o",
"1Fghq6cgdJEDr6gQBmvba3t6aXAkyZyjr2",
"142KsfJLvEA5FJxAgKm9ZDtFVjkRaPdu82",
}
total = types.Coin * 30000
Addr1,
Addr2,
Addr3,
Addr4,
Addr5,
Addr6,
Addr7,
Addr8,
Addr9,
Addr10,
Addr11,
Addr12,
Addr13,
Addr14,
Addr15,
Addr16,
Addr17,
}
total = types.Coin * 30000
)
func init() {
......@@ -547,7 +574,7 @@ func TestVerifyMinerAddr(t *testing.T) {
// 授权地址AddrD
for _, addr := range addrs {
tkBind := &ticketTy.TicketBind{
MinerAddress: AddrD,
MinerAddress: AddrD,
ReturnAddress: addr,
}
stateDB.Set(ticket.BindKey(addr), types.Encode(tkBind))
......@@ -565,7 +592,7 @@ func TestVerifyMinerAddr(t *testing.T) {
// ErrBindAddr
testf = "1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj"
tkBind := &ticketTy.TicketBind{
MinerAddress: AddrA,
MinerAddress: AddrA,
ReturnAddress: testf,
}
stateDB.Set(ticket.BindKey(testf), types.Encode(tkBind))
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"testing"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestExecLocalChange(t *testing.T) {
testexecLocalChange(t, false)
testexecLocalChange(t, true)
}
func testexecLocalChange(t *testing.T, auto bool) {
_, sdb, kvdb := util.CreateTestDB()
au := &Autonomy{}
au.SetLocalDB(kvdb)
//TyLogPropChange
cur := &auty.AutonomyProposalChange{
PropChange: &auty.ProposalChange{},
CurRule: &auty.RuleConfig{},
VoteResult: &auty.VoteResult{},
Status: auty.AutonomyStatusProposalChange,
Address: "11111111111111",
Height: 1,
Index: 2,
}
receiptChange := &auty.ReceiptProposalChange{
Prev: nil,
Current: cur,
}
receipt := &types.ReceiptData{
Logs: []*types.ReceiptLog{
{Ty: auty.TyLogPropChange, Log: types.Encode(receiptChange)},
},
}
var set *types.LocalDBSet
var err error
if !auto {
set, err = au.execLocalChange(receipt)
require.NoError(t, err)
require.NotNil(t, set)
} else {
tx, err := types.CreateFormatTx(types.ExecName(auty.AutonomyX), nil)
assert.NoError(t, err)
set, err = au.execAutoLocalChange(tx, receipt)
require.NoError(t, err)
require.NotNil(t, set)
}
//save to database
saveKvs(sdb, set.KV)
// check
checkExecLocalChange(t, kvdb, cur)
// TyLogRvkPropChange
pre1 := copyAutonomyProposalChange(cur)
cur.Status = auty.AutonomyStatusRvkPropChange
receiptChange1 := &auty.ReceiptProposalChange{
Prev: pre1,
Current: cur,
}
if !auto {
set, err = au.execLocalChange(&types.ReceiptData{
Logs: []*types.ReceiptLog{
{Ty: auty.TyLogRvkPropChange, Log: types.Encode(receiptChange1)},
},
})
require.NoError(t, err)
require.NotNil(t, set)
} else {
tx, err := types.CreateFormatTx(types.ExecName(auty.AutonomyX), nil)
assert.NoError(t, err)
set, err = au.execAutoLocalChange(tx,
&types.ReceiptData{
Logs: []*types.ReceiptLog{
{Ty: auty.TyLogRvkPropChange, Log: types.Encode(receiptChange1)},
},
})
require.NoError(t, err)
require.NotNil(t, set)
}
//save to database
saveKvs(sdb, set.KV)
// check
checkExecLocalChange(t, kvdb, cur)
// TyLogVotePropChange
cur.Status = auty.AutonomyStatusProposalChange
pre2 := copyAutonomyProposalChange(cur)
cur.Status = auty.AutonomyStatusVotePropChange
cur.Address = "2222222222222"
receiptChange2 := &auty.ReceiptProposalChange{
Prev: pre2,
Current: cur,
}
if !auto {
set, err = au.execLocalChange(&types.ReceiptData{
Logs: []*types.ReceiptLog{
{Ty: auty.TyLogVotePropChange, Log: types.Encode(receiptChange2)},
},
})
require.NoError(t, err)
require.NotNil(t, set)
} else {
tx, err := types.CreateFormatTx(types.ExecName(auty.AutonomyX), nil)
assert.NoError(t, err)
set, err = au.execAutoLocalChange(tx,
&types.ReceiptData{
Logs: []*types.ReceiptLog{
{Ty: auty.TyLogVotePropChange, Log: types.Encode(receiptChange2)},
},
})
require.NoError(t, err)
require.NotNil(t, set)
}
//save to database
saveKvs(sdb, set.KV)
// check
checkExecLocalChange(t, kvdb, cur)
}
func TestExecDelLocalChange(t *testing.T) {
testexecDelLocalChange(t)
}
func testexecDelLocalChange(t *testing.T) {
_, sdb, kvdb := util.CreateTestDB()
au := &Autonomy{}
au.SetLocalDB(kvdb)
//TyLogPropChange
cur := &auty.AutonomyProposalChange{
PropChange: &auty.ProposalChange{},
CurRule: &auty.RuleConfig{},
VoteResult: &auty.VoteResult{},
Status: auty.AutonomyStatusProposalChange,
Address: "11111111111111",
Height: 1,
Index: 2,
}
receiptChange := &auty.ReceiptProposalChange{
Prev: nil,
Current: cur,
}
receipt := &types.ReceiptData{
Logs: []*types.ReceiptLog{
{Ty: auty.TyLogPropChange, Log: types.Encode(receiptChange)},
},
}
// 先执行local然后进行删除
tx, err := types.CreateFormatTx(types.ExecName(auty.AutonomyX), nil)
assert.NoError(t, err)
set, err := au.execAutoLocalChange(tx, receipt)
require.NoError(t, err)
require.NotNil(t, set)
saveKvs(sdb, set.KV)
set, err = au.execAutoDelLocal(tx, receipt)
require.NoError(t, err)
require.NotNil(t, set)
saveKvs(sdb, set.KV)
// check
table := NewChangeTable(au.GetLocalDB())
query := table.GetQuery(kvdb)
_, err = query.ListIndex("primary", nil, nil, 10, 0)
assert.Equal(t, err, types.ErrNotFound)
_, err = query.ListIndex("addr", nil, nil, 10, 0)
assert.Equal(t, err, types.ErrNotFound)
_, err = query.ListIndex("status", nil, nil, 10, 0)
assert.Equal(t, err, types.ErrNotFound)
_, err = query.ListIndex("addr_status", nil, nil, 10, 0)
assert.Equal(t, err, types.ErrNotFound)
// TyLogVotePropChange
pre1 := copyAutonomyProposalChange(cur)
cur.Status = auty.AutonomyStatusVotePropChange
receiptChange2 := &auty.ReceiptProposalChange{
Prev: pre1,
Current: cur,
}
recpt := &types.ReceiptData{
Logs: []*types.ReceiptLog{
{Ty: auty.TyLogVotePropChange, Log: types.Encode(receiptChange2)},
}}
// 先执行local然后进行删除
// 自动回退测试时候,需要先设置一个前置状态
tx, err = types.CreateFormatTx(types.ExecName(auty.AutonomyX), nil)
assert.NoError(t, err)
set, err = au.execAutoLocalChange(tx, receipt)
require.NoError(t, err)
require.NotNil(t, set)
saveKvs(sdb, set.KV)
// 正常测试退回
tx, err = types.CreateFormatTx(types.ExecName(auty.AutonomyX), nil)
assert.NoError(t, err)
set, err = au.execAutoLocalChange(tx, recpt)
require.NoError(t, err)
require.NotNil(t, set)
saveKvs(sdb, set.KV)
// check
checkExecLocalChange(t, kvdb, cur)
set, err = au.execAutoDelLocal(tx, recpt)
require.NoError(t, err)
require.NotNil(t, set)
saveKvs(sdb, set.KV)
// check
checkExecLocalChange(t, kvdb, pre1)
}
func TestGetProposalChange(t *testing.T) {
au := &Autonomy{
dapp.DriverBase{},
}
_, storedb, _ := util.CreateTestDB()
au.SetStateDB(storedb)
tx := "1111111111111111111"
storedb.Set(propChangeID(tx), types.Encode(&auty.AutonomyProposalChange{}))
rsp, err := au.getProposalChange(&types.ReqString{Data: tx})
require.NoError(t, err)
require.NotNil(t, rsp)
require.Equal(t, len(rsp.(*auty.ReplyQueryProposalChange).PropChanges), 1)
}
func TestListProposalChange(t *testing.T) {
au := &Autonomy{
dapp.DriverBase{},
}
_, sdb, kvdb := util.CreateTestDB()
au.SetLocalDB(kvdb)
type statu struct {
status int32
height int64
index int64
}
testcase1 := []statu{
{auty.AutonomyStatusRvkPropChange, 10, 2},
{auty.AutonomyStatusVotePropChange, 15, 1},
{auty.AutonomyStatusTmintPropChange, 20, 1},
}
testcase2 := []statu{
{auty.AutonomyStatusProposalChange, 10, 1},
{auty.AutonomyStatusProposalChange, 20, 2},
{auty.AutonomyStatusProposalChange, 20, 5},
}
var testcase []statu
testcase = append(testcase, testcase1...)
testcase = append(testcase, testcase2...)
cur := &auty.AutonomyProposalChange{
PropChange: &auty.ProposalChange{},
CurRule: &auty.RuleConfig{},
VoteResult: &auty.VoteResult{},
Status: auty.AutonomyStatusProposalChange,
Address: "11111111111111",
Height: 1,
Index: 2,
}
//将数据保存下去
var kvs []*types.KeyValue
table := NewChangeTable(kvdb)
for _, tcase := range testcase {
cur.Status = tcase.status
cur.Height = tcase.height
cur.Index = int32(tcase.index)
err := table.Replace(cur)
require.NoError(t, err)
kv, err := table.Save()
require.NoError(t, err)
kvs = append(kvs, kv...)
}
saveKvs(sdb, kvs)
// 反向查找
req := &auty.ReqQueryProposalChange{
Status: auty.AutonomyStatusProposalChange,
Count: 10,
Direction: 0,
Index: -1,
}
rsp, err := au.listProposalChange(req)
require.NoError(t, err)
require.Equal(t, len(rsp.(*auty.ReplyQueryProposalChange).PropChanges), len(testcase2))
k := 2
for _, tcase := range testcase2 {
require.Equal(t, rsp.(*auty.ReplyQueryProposalChange).PropChanges[k].Height, tcase.height)
require.Equal(t, rsp.(*auty.ReplyQueryProposalChange).PropChanges[k].Index, int32(tcase.index))
k--
}
// 正向查找
req = &auty.ReqQueryProposalChange{
Status: auty.AutonomyStatusProposalChange,
Count: 10,
Direction: 1,
Index: -1,
}
rsp, err = au.listProposalChange(req)
require.NoError(t, err)
require.Equal(t, len(rsp.(*auty.ReplyQueryProposalChange).PropChanges), len(testcase2))
for i, tcase := range testcase2 {
require.Equal(t, rsp.(*auty.ReplyQueryProposalChange).PropChanges[i].Height, tcase.height)
require.Equal(t, rsp.(*auty.ReplyQueryProposalChange).PropChanges[i].Index, int32(tcase.index))
}
// 翻页查找
req = &auty.ReqQueryProposalChange{
Status: auty.AutonomyStatusProposalChange,
Count: 1,
Direction: 0,
Index: -1,
}
rsp, err = au.listProposalChange(req)
require.NoError(t, err)
require.Equal(t, len(rsp.(*auty.ReplyQueryProposalChange).PropChanges), 1)
height := rsp.(*auty.ReplyQueryProposalChange).PropChanges[0].Height
index := rsp.(*auty.ReplyQueryProposalChange).PropChanges[0].Index
require.Equal(t, height, testcase2[2].height)
require.Equal(t, index, int32(testcase2[2].index))
//
req = &auty.ReqQueryProposalChange{
Status: auty.AutonomyStatusProposalChange,
Count: 10,
Direction: 0,
Height: height,
Index: index,
}
rsp, err = au.listProposalChange(req)
require.NoError(t, err)
require.Equal(t, len(rsp.(*auty.ReplyQueryProposalChange).PropChanges), 2)
require.Equal(t, rsp.(*auty.ReplyQueryProposalChange).PropChanges[0].Height, testcase2[1].height)
require.Equal(t, rsp.(*auty.ReplyQueryProposalChange).PropChanges[0].Index, int32(testcase2[1].index))
require.Equal(t, rsp.(*auty.ReplyQueryProposalChange).PropChanges[1].Height, testcase2[0].height)
require.Equal(t, rsp.(*auty.ReplyQueryProposalChange).PropChanges[1].Index, int32(testcase2[0].index))
}
func checkExecLocalChange(t *testing.T, kvdb db.KVDB, cur *auty.AutonomyProposalChange) {
table := NewChangeTable(kvdb)
query := table.GetQuery(kvdb)
rows, err := query.ListIndex("primary", nil, nil, 10, 0)
assert.Equal(t, err, nil)
assert.Equal(t, string(rows[0].Primary), dapp.HeightIndexStr(1, 2))
rows, err = query.ListIndex("addr", nil, nil, 10, 0)
assert.Equal(t, err, nil)
assert.Equal(t, 1, len(rows))
rows, err = query.ListIndex("status", nil, nil, 10, 0)
assert.Equal(t, err, nil)
assert.Equal(t, 1, len(rows))
rows, err = query.ListIndex("addr_status", nil, nil, 10, 0)
assert.Equal(t, err, nil)
assert.Equal(t, 1, len(rows))
prop, ok := rows[0].Data.(*auty.AutonomyProposalChange)
assert.Equal(t, true, ok)
assert.Equal(t, prop.Status, cur.Status)
assert.Equal(t, prop.Address, cur.Address)
assert.Equal(t, prop.Height, cur.Height)
assert.Equal(t, prop.Index, cur.Index)
}
......@@ -8,10 +8,8 @@ import (
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
func (a *action) propChange(prob *auty.ProposalChange) (*types.Receipt, error) {
//如果全小于等于0,则说明该提案规则参数不正确
if prob == nil || len(prob.Changes) == 0 {
......@@ -56,10 +54,10 @@ func (a *action) propChange(prob *auty.ProposalChange) (*types.Receipt, error) {
kv = append(kv, receipt.KV...)
cur := &auty.AutonomyProposalChange{
PropChange: prob,
PropChange: prob,
CurRule: rule,
Board: new,
VoteResult: &auty.VoteResult{TotalVotes:int32(len(act.Boards))},
VoteResult: &auty.VoteResult{TotalVotes: int32(len(act.Boards))},
Status: auty.AutonomyStatusProposalChange,
Address: a.fromaddr,
Height: a.height,
......@@ -168,15 +166,10 @@ func (a *action) votePropChange(voteProb *auty.VoteProposalChange) (*types.Recei
// 更新投票记录
votes.Address = append(votes.Address, a.fromaddr)
// 获取可投票数
vtCouts, err := a.getAddressVotes(a.fromaddr, start)
if err != nil {
return nil, err
}
if voteProb.Approve {
cur.VoteResult.ApproveVotes += vtCouts
cur.VoteResult.ApproveVotes++
} else {
cur.VoteResult.OpposeVotes += vtCouts
cur.VoteResult.OpposeVotes++
}
var logs []*types.ReceiptLog
......@@ -331,7 +324,7 @@ func (a *action) checkChangeable(act *auty.ActiveBoard, change []*auty.Change) (
return nil, auty.ErrBoardNumber
}
new := &auty.ActiveBoard{
Amount: act.Amount,
Amount: act.Amount,
StartHeight: act.StartHeight,
}
for k := range mpBd {
......@@ -359,13 +352,14 @@ func copyAutonomyProposalChange(cur *auty.AutonomyProposalChange) *auty.Autonomy
}
newAut := *cur
if cur.PropChange != nil {
newPropChange := *cur.GetPropChange()
newPropChange := *cur.PropChange
newAut.PropChange = &newPropChange
if cur.PropChange.Changes != nil {
chs := cur.GetPropChange().GetChanges()
for _, ch := range chs {
newAut.PropChange.Changes = make([]*auty.Change, len(cur.PropChange.Changes))
chs := cur.PropChange.Changes
for i, ch := range chs {
newch := *ch
newAut.PropChange.Changes = append(newAut.PropChange.Changes, &newch)
newAut.PropChange.Changes[i] = &newch
}
}
}
......@@ -375,6 +369,10 @@ func copyAutonomyProposalChange(cur *auty.AutonomyProposalChange) *auty.Autonomy
}
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 {
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"testing"
"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"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
func InitChange(t *testing.T, stateDB dbm.KV) {
act := &auty.ActiveBoard{
Boards: boards,
}
err := stateDB.Set(activeBoardID(), types.Encode(act))
assert.NoError(t, err)
}
func TestRevokeProposalChange(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv()
InitChange(t, stateDB)
// PropChange
testPropChange(t, env, exec, stateDB, kvdb, true)
//RevokeProposalChange
revokeProposalChange(t, env, exec, stateDB, kvdb, false)
}
func TestVoteProposalChange(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv()
InitChange(t, stateDB)
// PropChange
testPropChange(t, env, exec, stateDB, kvdb, true)
//voteProposalChange
voteProposalChange(t, env, exec, stateDB, kvdb, true)
}
func TestTerminateProposalChange(t *testing.T) {
env, exec, stateDB, kvdb := InitEnv()
InitChange(t, stateDB)
// PropChange
testPropChange(t, env, exec, stateDB, kvdb, true)
//terminateProposalChange
terminateProposalChange(t, env, exec, stateDB, kvdb, true)
}
func testPropChange(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB dbm.KV, kvdb dbm.KVDB, save bool) {
opt1 := &auty.ProposalChange{
Year: 2019,
Month: 7,
Day: 10,
Changes: []*auty.Change{{Cancel: true, Addr: AddrA}},
StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + 10,
}
pbtx, err := propChangeTx(opt1)
require.NoError(t, err)
pbtx, err = signTx(pbtx, PrivKeyA)
require.NoError(t, err)
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
receipt, err := exec.Exec(pbtx, int(1))
require.NoError(t, err)
require.NotNil(t, receipt)
if save {
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
}
// local
receiptData := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err := exec.ExecLocal(pbtx, receiptData, int(1))
require.NoError(t, err)
require.NotNil(t, set)
if save {
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
}
// 更新tahash
env.txHash = common.ToHex(pbtx.Hash())
env.startHeight = opt1.StartBlockHeight
env.endHeight = opt1.EndBlockHeight
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
require.Equal(t, proposalAmount, account.Frozen)
}
func propChangeTx(parm *auty.ProposalChange) (*types.Transaction, error) {
if parm == nil {
return nil, types.ErrInvalidParam
}
val := &auty.AutonomyAction{
Ty: auty.AutonomyActionPropChange,
Value: &auty.AutonomyAction_PropChange{PropChange: parm},
}
return types.CreateFormatTx(types.ExecName(auty.AutonomyX), types.Encode(val))
}
func revokeProposalChange(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB dbm.KV, kvdb dbm.KVDB, save bool) {
proposalID := env.txHash
opt2 := &auty.RevokeProposalChange{
ProposalID: proposalID,
}
rtx, err := revokeProposalChangeTx(opt2)
require.NoError(t, err)
rtx, err = signTx(rtx, PrivKeyA)
require.NoError(t, err)
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
receipt, err := exec.Exec(rtx, 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(rtx, receiptData, int(1))
require.NoError(t, err)
require.NotNil(t, set)
if save {
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
}
// del
set, err = exec.ExecDelLocal(rtx, receiptData, int(1))
require.NoError(t, err)
require.NotNil(t, set)
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
require.Equal(t, int64(0), account.Frozen)
}
func revokeProposalChangeTx(parm *auty.RevokeProposalChange) (*types.Transaction, error) {
if parm == nil {
return nil, types.ErrInvalidParam
}
val := &auty.AutonomyAction{
Ty: auty.AutonomyActionRvkPropChange,
Value: &auty.AutonomyAction_RvkPropChange{RvkPropChange: parm},
}
return types.CreateFormatTx(types.ExecName(auty.AutonomyX), types.Encode(val))
}
func voteProposalChange(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB dbm.KV, kvdb dbm.KVDB, save bool) {
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,
Frozen: 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
type record struct {
priv string
appr bool
}
records := []record{
//{PrivKeyA, false},
{PrivKeyB, true},
{PrivKeyC, true},
{PrivKeyD, true},
{PrivKey1, false},
{PrivKey2, true},
{PrivKey3, true},
{PrivKey4, true},
{PrivKey5, true},
{PrivKey6, true},
{PrivKey7, true},
{PrivKey8, true},
{PrivKey9, true},
{PrivKey10, true},
{PrivKey11, true},
{PrivKey12, true},
}
for _, record := range records {
opt := &auty.VoteProposalChange{
ProposalID: proposalID,
Approve: record.appr,
}
tx, err := voteProposalChangeTx(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)
}
}
// del
set, err = exec.ExecDelLocal(tx, receiptData, int(1))
require.NoError(t, err)
require.NotNil(t, set)
// 每次需要重新设置
acc := &types.Account{
Currency: 0,
Frozen: total,
}
val := types.Encode(acc)
values := [][]byte{val}
api.On("StoreGet", mock.Anything).Return(&types.StoreReplyValue{Values: values}, nil).Once()
exec.SetAPI(api)
}
// 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(autonomyFundAddr, address.ExecAddress(auty.AutonomyX))
require.Equal(t, int64(proposalAmount), account.Balance)
// status
value, err := stateDB.Get(propChangeID(proposalID))
require.NoError(t, err)
cur := &auty.AutonomyProposalChange{}
err = types.Decode(value, cur)
require.NoError(t, err)
require.Equal(t, int32(auty.AutonomyStatusTmintPropChange), cur.Status)
require.Equal(t, AddrA, cur.Address)
require.Equal(t, true, cur.VoteResult.Pass)
value, err = stateDB.Get(activeBoardID())
require.NoError(t, err)
act := &auty.ActiveBoard{}
err = types.Decode(value, act)
require.NoError(t, err)
require.Equal(t, act.Revboards[0], AddrA)
require.Equal(t, len(act.Boards), len(boards)-1)
}
func voteProposalChangeTx(parm *auty.VoteProposalChange) (*types.Transaction, error) {
if parm == nil {
return nil, types.ErrInvalidParam
}
val := &auty.AutonomyAction{
Ty: auty.AutonomyActionVotePropChange,
Value: &auty.AutonomyAction_VotePropChange{VotePropChange: parm},
}
return types.CreateFormatTx(types.ExecName(auty.AutonomyX), types.Encode(val))
}
func terminateProposalChange(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB dbm.KV, kvdb dbm.KVDB, save bool) {
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()
exec.SetAPI(api)
proposalID := env.txHash
opt := &auty.TerminateProposalChange{
ProposalID: proposalID,
}
tx, err := terminateProposalChangeTx(opt)
require.NoError(t, err)
tx, err = signTx(tx, PrivKeyA)
require.NoError(t, err)
exec.SetEnv(env.endHeight+1, 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)
}
}
// del
set, err = exec.ExecDelLocal(tx, receiptData, int(1))
require.NoError(t, err)
require.NotNil(t, set)
// check
accCoin := account.NewCoinsAccount()
accCoin.SetDB(stateDB)
account := accCoin.LoadExecAccount(AddrA, address.ExecAddress(auty.AutonomyX))
require.Equal(t, int64(0), account.Frozen)
}
func terminateProposalChangeTx(parm *auty.TerminateProposalChange) (*types.Transaction, error) {
if parm == nil {
return nil, types.ErrInvalidParam
}
val := &auty.AutonomyAction{
Ty: auty.AutonomyActionTmintPropChange,
Value: &auty.AutonomyAction_TmintPropChange{TmintPropChange: parm},
}
return types.CreateFormatTx(types.ExecName(auty.AutonomyX), types.Encode(val))
}
func TestGetChangeReceiptLog(t *testing.T) {
pre := &auty.AutonomyProposalChange{
PropChange: &auty.ProposalChange{Year: 1800, Month: 1},
VoteResult: &auty.VoteResult{TotalVotes: 100},
Status: 1,
Address: "121",
}
cur := &auty.AutonomyProposalChange{
PropChange: &auty.ProposalChange{Year: 1900, Month: 1},
VoteResult: &auty.VoteResult{TotalVotes: 100},
Status: 2,
Address: "123",
}
log := getChangeReceiptLog(pre, cur, 2)
require.Equal(t, int32(2), log.Ty)
recpt := &auty.ReceiptProposalChange{}
err := types.Decode(log.Log, recpt)
require.NoError(t, err)
require.Equal(t, int32(1800), recpt.Prev.PropChange.Year)
require.Equal(t, int32(1900), recpt.Current.PropChange.Year)
}
func TestCheckChangeable(t *testing.T) {
at := newAutonomy().(*Autonomy)
tx := &types.Transaction{}
action := newAction(at, tx, 0)
act := &auty.ActiveBoard{
Boards: boards,
}
// 正常撤销一个地址
changes := []*auty.Change{{Cancel: true, Addr: AddrA}}
cur, err := action.checkChangeable(act, changes)
require.NoError(t, err)
require.Equal(t, len(cur.Boards), len(boards)-1)
require.Equal(t, cur.Revboards[0], AddrA)
// 恢复撤销地址
changes = []*auty.Change{
{Cancel: false, Addr: AddrA},
}
ncur, err := action.checkChangeable(cur, changes)
require.NoError(t, err)
require.Equal(t, len(ncur.Boards), len(boards))
require.Equal(t, len(ncur.Revboards), 0)
// 撤销两个地址,撤销不够最小minBoards
changes = []*auty.Change{
{Cancel: true, Addr: AddrA},
{Cancel: true, Addr: AddrB},
}
_, err = action.checkChangeable(act, changes)
require.Equal(t, err, auty.ErrBoardNumber)
// 恢复一个没有被撤销的地址
changes = []*auty.Change{
{Cancel: false, Addr: AddrA},
}
_, err = action.checkChangeable(act, changes)
require.Equal(t, err, auty.ErrChangeBoardAddr)
// 撤销一个不存在地址
changes = []*auty.Change{
{Cancel: true, Addr: "1111111111"},
}
_, err = action.checkChangeable(act, changes)
require.Equal(t, err, auty.ErrChangeBoardAddr)
}
func TestCopyAutonomyProposalChange(t *testing.T) {
require.Nil(t, copyAutonomyProposalChange(nil))
cur := &auty.AutonomyProposalChange{
PropChange: &auty.ProposalChange{
Year: 1900,
Month: 1,
Changes: []*auty.Change{{Cancel: true, Addr: "11"}, {Cancel: false, Addr: "12"}},
},
CurRule: &auty.RuleConfig{BoardApproveRatio: 100},
Board: &auty.ActiveBoard{
Boards: []string{"11", "12"},
Revboards: []string{"13", "15"},
Amount: 100,
},
VoteResult: &auty.VoteResult{TotalVotes: 100},
Status: 2,
Address: "123",
}
pre := copyAutonomyProposalChange(cur)
cur.PropChange.Year = 1800
cur.PropChange.Month = 2
cur.PropChange.Changes[0].Cancel = false
cur.PropChange.Changes[0].Addr = "21"
cur.PropChange.Changes[1].Cancel = true
cur.PropChange.Changes[1].Addr = "22"
cur.CurRule.BoardApproveRatio = 90
cur.Board.Boards[0] = "21"
cur.Board.Boards[1] = "22"
cur.Board.Revboards[0] = "23"
cur.Board.Revboards[0] = "25"
cur.Board.Amount = 90
cur.VoteResult.TotalVotes = 50
cur.Address = "234"
cur.Status = 1
assert.Equal(t, 1900, int(pre.PropChange.Year))
assert.Equal(t, 1, int(pre.PropChange.Month))
assert.Equal(t, &auty.Change{Cancel: true, Addr: "11"}, pre.PropChange.Changes[0])
assert.Equal(t, &auty.Change{Cancel: false, Addr: "12"}, pre.PropChange.Changes[1])
assert.Equal(t, "11", pre.Board.Boards[0])
assert.Equal(t, "12", pre.Board.Boards[1])
assert.Equal(t, "13", pre.Board.Revboards[0])
assert.Equal(t, "15", pre.Board.Revboards[1])
assert.Equal(t, 100, int(pre.Board.Amount))
assert.Equal(t, 100, int(pre.VoteResult.TotalVotes))
assert.Equal(t, "123", pre.Address)
assert.Equal(t, 2, int(pre.Status))
}
......@@ -105,7 +105,6 @@ func (a *Autonomy) Exec_CommentProp(payload *auty.Comment, tx *types.Transaction
return action.commentProp(payload)
}
// 提案修改董事会成员相关
// Exec_PropChange 创建提案规则
......@@ -130,4 +129,4 @@ func (a *Autonomy) Exec_VotePropChange(payload *auty.VoteProposalChange, tx *typ
func (a *Autonomy) Exec_TmintPropChange(payload *auty.TerminateProposalChange, tx *types.Transaction, index int) (*types.Receipt, error) {
action := newAction(a, tx, int32(index))
return action.tmintPropChange(payload)
}
\ No newline at end of file
}
......@@ -85,7 +85,6 @@ func (a *Autonomy) ExecLocal_CommentProp(payload *auty.Comment, tx *types.Transa
return a.execAutoLocalCommentProp(tx, receiptData)
}
// 提案修改董事会成员相关
// ExecLocal_PropChange 创建提案规则
......@@ -106,4 +105,4 @@ func (a *Autonomy) ExecLocal_VotePropChange(payload *auty.VoteProposalChange, tx
// ExecLocal_TmintPropChange 终止提案规则
func (a *Autonomy) ExecLocal_TmintPropChange(payload *auty.TerminateProposalChange, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execAutoLocalChange(tx, receiptData)
}
\ No newline at end of file
}
......@@ -78,4 +78,4 @@ var (
func propChangeID(txHash string) []byte {
return []byte(fmt.Sprintf("%s%s", changePrefix, txHash))
}
\ No newline at end of file
}
......@@ -13,8 +13,8 @@ import (
)
const (
maxBoardPeriodAmount = types.Coin * 10000 * 300 // 每个时期董事会审批最大额度300万
boardPeriod = 17280 * 30 * 1 // 时期为一个月
maxBoardPeriodAmount = types.Coin * 10000 * 300 // 每个时期董事会审批最大额度300万
boardPeriod = 17280 * 30 * 1 // 时期为一个月
)
func (a *action) propProject(prob *auty.ProposalProject) (*types.Receipt, error) {
......@@ -37,10 +37,10 @@ func (a *action) propProject(prob *auty.ProposalProject) (*types.Receipt, error)
}
// 检查是否可以对已审批额度归0,如果可以则设置kv
var kva *types.KeyValue
if a.height > pboard.StartHeight + boardPeriod {
if a.height > pboard.StartHeight+boardPeriod {
pboard.StartHeight = a.height
pboard.Amount = 0
kva = &types.KeyValue{Key:activeBoardID(), Value:types.Encode(pboard)}
kva = &types.KeyValue{Key: activeBoardID(), Value: types.Encode(pboard)}
}
// 检查额度
pass := a.checkPeriodAmount(pboard, prob.Amount)
......@@ -593,7 +593,7 @@ func (a *action) checkPeriodAmount(act *auty.ActiveBoard, amount int64) bool {
if act == nil {
return false
}
if act.Amount + amount >= maxBoardPeriodAmount {
if act.Amount+amount >= maxBoardPeriodAmount {
return false
}
return true
......@@ -604,10 +604,10 @@ func (a *action) updatePeriodAmount(amount int64) (*types.KeyValue, error) {
if err != nil {
return nil, err
}
if a.height > act.StartHeight + boardPeriod {
if a.height > act.StartHeight+boardPeriod {
act.StartHeight = a.height
act.Amount = 0
}
act.Amount += amount
return &types.KeyValue{Key:activeBoardID(), Value:types.Encode(act)}, nil
}
\ No newline at end of file
return &types.KeyValue{Key: activeBoardID(), Value: types.Encode(act)}, nil
}
......@@ -52,4 +52,4 @@ func (a *Autonomy) Query_GetProposalChange(in *types.ReqString) (types.Message,
// Query_ListProposalChange 批量查询
func (a *Autonomy) Query_ListProposalChange(in *auty.ReqQueryProposalChange) (types.Message, error) {
return a.listProposalChange(in)
}
\ No newline at end of file
}
......@@ -9,8 +9,8 @@ import (
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/system/dapp"
)
const (
......@@ -19,37 +19,36 @@ const (
// 最大董事会赞成率
maxBoardApproveRatio = 66
// 最小全体持票人否决率
minPubOpposeRatio = 33
minPubOpposeRatio = 33
// 最大全体持票人否决率
maxPubOpposeRatio = 50
maxPubOpposeRatio = 50
// 最小公示周期
minPublicPeriod int32 = 17280 * 7
minPublicPeriod int32 = 17280 * 7
// 最大公示周期
maxPublicPeriod int32 = 17280 * 14
maxPublicPeriod int32 = 17280 * 14
// 最小重大项目阈值
minLargeProjectAmount = types.Coin * 100 * 10000
// 最大重大项目阈值
maxLargeProjectAmount = types.Coin * 300 * 10000
// 最小提案金
minProposalAmount = types.Coin * 20
minProposalAmount = types.Coin * 20
// 最大提案金
maxProposalAmount = types.Coin * 2000
maxProposalAmount = types.Coin * 2000
)
func (a *action) propRule(prob *auty.ProposalRule) (*types.Receipt, error) {
//如果全小于等于0,则说明该提案规则参数不正确
if prob.RuleCfg == nil || prob.RuleCfg.BoardApproveRatio <= 0 && prob.RuleCfg.PubOpposeRatio <= 0 &&
prob.RuleCfg.ProposalAmount <= 0 && prob.RuleCfg.LargeProjectAmount <= 0 && prob.RuleCfg.PublicPeriod <= 0{
prob.RuleCfg.ProposalAmount <= 0 && prob.RuleCfg.LargeProjectAmount <= 0 && prob.RuleCfg.PublicPeriod <= 0 {
alog.Error("propRule ", "ProposalRule RuleCfg invaild or have no modify param", prob.RuleCfg)
return nil, types.ErrInvalidParam
}
if prob.RuleCfg.BoardApproveRatio > maxBoardApproveRatio || prob.RuleCfg.BoardApproveRatio < minBoardApproveRatio ||
prob.RuleCfg.PubOpposeRatio > maxPubOpposeRatio || prob.RuleCfg.PubOpposeRatio < minPubOpposeRatio ||
prob.RuleCfg.PublicPeriod > maxPublicPeriod || prob.RuleCfg.PublicPeriod < minPublicPeriod ||
prob.RuleCfg.PublicPeriod > maxPublicPeriod || prob.RuleCfg.PublicPeriod < minPublicPeriod ||
prob.RuleCfg.LargeProjectAmount > maxLargeProjectAmount || prob.RuleCfg.LargeProjectAmount < minLargeProjectAmount ||
prob.RuleCfg.ProposalAmount > maxProposalAmount || prob.RuleCfg.ProposalAmount < minProposalAmount{
alog.Error("propRule RuleCfg invaild", "ruleCfg", prob.RuleCfg)
prob.RuleCfg.ProposalAmount > maxProposalAmount || prob.RuleCfg.ProposalAmount < minProposalAmount {
alog.Error("propRule RuleCfg invaild", "ruleCfg", prob.RuleCfg)
return nil, types.ErrInvalidParam
}
if prob.StartBlockHeight < a.height || prob.EndBlockHeight < a.height {
......
......@@ -23,9 +23,9 @@ import (
const (
testBoardApproveRatio int32 = 60
testPubOpposeRatio int32 = 35
testProposalAmount = minProposalAmount * 2
testLargeProjectAmount = minLargeProjectAmount * 2
testPublicPeriod = minPublicPeriod
testProposalAmount = minProposalAmount * 2
testLargeProjectAmount = minLargeProjectAmount * 2
testPublicPeriod = minPublicPeriod
)
func TestRevokeProposalRule(t *testing.T) {
......
......@@ -47,7 +47,7 @@ const (
TyLogVotePropRule = 2123
TyLogTmintPropRule = 2124
TyLogCommentProp = 2131
TyLogCommentProp = 2131
TyLogPropChange = 2141
TyLogRvkPropChange = 2142
......@@ -88,8 +88,6 @@ const (
AutonomyStatusTmintPropChange
)
const (
// GetProposalBoard 用于在cmd里面的区分不同的查询
GetProposalBoard = "GetProposalBoard"
......
......@@ -73,9 +73,9 @@ func ParseX509CertificateToSm2(x509Cert *x509.Certificate) *sm2.Certificate {
UnknownExtKeyUsage: x509Cert.UnknownExtKeyUsage,
BasicConstraintsValid: x509Cert.BasicConstraintsValid,
IsCA: x509Cert.IsCA,
MaxPathLen: x509Cert.MaxPathLen,
MaxPathLenZero: x509Cert.MaxPathLenZero,
IsCA: x509Cert.IsCA,
MaxPathLen: x509Cert.MaxPathLen,
MaxPathLenZero: x509Cert.MaxPathLenZero,
SubjectKeyId: x509Cert.SubjectKeyId,
AuthorityKeyId: x509Cert.AuthorityKeyId,
......@@ -136,9 +136,9 @@ func ParseSm2CertificateToX509(sm2Cert *sm2.Certificate) *x509.Certificate {
UnknownExtKeyUsage: sm2Cert.UnknownExtKeyUsage,
BasicConstraintsValid: sm2Cert.BasicConstraintsValid,
IsCA: sm2Cert.IsCA,
MaxPathLen: sm2Cert.MaxPathLen,
MaxPathLenZero: sm2Cert.MaxPathLenZero,
IsCA: sm2Cert.IsCA,
MaxPathLen: sm2Cert.MaxPathLen,
MaxPathLenZero: sm2Cert.MaxPathLenZero,
SubjectKeyId: sm2Cert.SubjectKeyId,
AuthorityKeyId: sm2Cert.AuthorityKeyId,
......
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