mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 15:25:18 +00:00
add mre fields to committee type
This commit is contained in:
parent
77553ed299
commit
57f4ca7c9a
@ -14,6 +14,8 @@ import (
|
|||||||
"github.com/kava-labs/kava/x/committee"
|
"github.com/kava-labs/kava/x/committee"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func d(s string) sdk.Dec { return sdk.MustNewDecFromStr(s) }
|
||||||
|
|
||||||
type ModuleTestSuite struct {
|
type ModuleTestSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
|
|
||||||
@ -35,9 +37,11 @@ func (suite *ModuleTestSuite) TestBeginBlock() {
|
|||||||
suite.app.InitializeFromGenesisStates()
|
suite.app.InitializeFromGenesisStates()
|
||||||
// TODO replace below with genesis state
|
// TODO replace below with genesis state
|
||||||
normalCom := committee.Committee{
|
normalCom := committee.Committee{
|
||||||
ID: 12,
|
ID: 12,
|
||||||
Members: suite.addresses[:2],
|
Members: suite.addresses[:2],
|
||||||
Permissions: []committee.Permission{committee.GodPermission{}},
|
Permissions: []committee.Permission{committee.GodPermission{}},
|
||||||
|
VoteThreshold: d("0.8"),
|
||||||
|
MaxProposalDuration: time.Hour * 24 * 7,
|
||||||
}
|
}
|
||||||
suite.keeper.SetCommittee(suite.ctx, normalCom)
|
suite.keeper.SetCommittee(suite.ctx, normalCom)
|
||||||
|
|
||||||
@ -51,7 +55,7 @@ func (suite *ModuleTestSuite) TestBeginBlock() {
|
|||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
// Run BeginBlocker
|
// Run BeginBlocker
|
||||||
proposalDurationLaterCtx := suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(committee.MaxProposalDuration))
|
proposalDurationLaterCtx := suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(normalCom.MaxProposalDuration))
|
||||||
suite.NotPanics(func() {
|
suite.NotPanics(func() {
|
||||||
committee.BeginBlocker(proposalDurationLaterCtx, abci.RequestBeginBlock{}, suite.keeper)
|
committee.BeginBlocker(proposalDurationLaterCtx, abci.RequestBeginBlock{}, suite.keeper)
|
||||||
})
|
})
|
||||||
|
@ -14,6 +14,7 @@ const (
|
|||||||
DefaultNextProposalID = types.DefaultNextProposalID
|
DefaultNextProposalID = types.DefaultNextProposalID
|
||||||
DefaultParamspace = types.DefaultParamspace
|
DefaultParamspace = types.DefaultParamspace
|
||||||
EventTypeSubmitProposal = types.EventTypeSubmitProposal
|
EventTypeSubmitProposal = types.EventTypeSubmitProposal
|
||||||
|
MaxDescriptionLength = types.MaxDescriptionLength
|
||||||
ModuleName = types.ModuleName
|
ModuleName = types.ModuleName
|
||||||
ProposalTypeCommitteeChange = types.ProposalTypeCommitteeChange
|
ProposalTypeCommitteeChange = types.ProposalTypeCommitteeChange
|
||||||
ProposalTypeCommitteeDelete = types.ProposalTypeCommitteeDelete
|
ProposalTypeCommitteeDelete = types.ProposalTypeCommitteeDelete
|
||||||
@ -53,14 +54,12 @@ var (
|
|||||||
Uint64FromBytes = types.Uint64FromBytes
|
Uint64FromBytes = types.Uint64FromBytes
|
||||||
|
|
||||||
// variable aliases
|
// variable aliases
|
||||||
ProposalHandler = client.ProposalHandler
|
ProposalHandler = client.ProposalHandler
|
||||||
CommitteeKeyPrefix = types.CommitteeKeyPrefix
|
CommitteeKeyPrefix = types.CommitteeKeyPrefix
|
||||||
MaxProposalDuration = types.MaxProposalDuration
|
ModuleCdc = types.ModuleCdc
|
||||||
ModuleCdc = types.ModuleCdc
|
NextProposalIDKey = types.NextProposalIDKey
|
||||||
NextProposalIDKey = types.NextProposalIDKey
|
ProposalKeyPrefix = types.ProposalKeyPrefix
|
||||||
ProposalKeyPrefix = types.ProposalKeyPrefix
|
VoteKeyPrefix = types.VoteKeyPrefix
|
||||||
VoteKeyPrefix = types.VoteKeyPrefix
|
|
||||||
VoteThreshold = types.VoteThreshold
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@ -189,8 +190,15 @@ func mustGetExampleCommitteeChangeProposal(cdc *codec.Codec) string {
|
|||||||
"A description of this proposal.",
|
"A description of this proposal.",
|
||||||
types.NewCommittee(
|
types.NewCommittee(
|
||||||
1,
|
1,
|
||||||
|
"The description of this committee.",
|
||||||
[]sdk.AccAddress{sdk.AccAddress(crypto.AddressHash([]byte("exampleAddres")))},
|
[]sdk.AccAddress{sdk.AccAddress(crypto.AddressHash([]byte("exampleAddres")))},
|
||||||
[]types.Permission{}, // TODO permissions
|
[]types.Permission{
|
||||||
|
types.ParamChangePermission{
|
||||||
|
AllowedParams: types.AllowedParams{{Subspace: "cdp", Key: "CircuitBreaker"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sdk.MustNewDecFromStr("0.8"),
|
||||||
|
time.Hour*24*7,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
exampleChangeProposalBz, err := cdc.MarshalJSONIndent(exampleChangeProposal, "", " ")
|
exampleChangeProposalBz, err := cdc.MarshalJSONIndent(exampleChangeProposal, "", " ")
|
||||||
|
@ -2,10 +2,12 @@ package keeper_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
||||||
"github.com/kava-labs/kava/app"
|
"github.com/kava-labs/kava/app"
|
||||||
@ -13,6 +15,8 @@ import (
|
|||||||
"github.com/kava-labs/kava/x/committee/types"
|
"github.com/kava-labs/kava/x/committee/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func d(s string) sdk.Dec { return sdk.MustNewDecFromStr(s) }
|
||||||
|
|
||||||
type KeeperTestSuite struct {
|
type KeeperTestSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
|
|
||||||
@ -33,8 +37,12 @@ func (suite *KeeperTestSuite) SetupTest() {
|
|||||||
func (suite *KeeperTestSuite) TestGetSetDeleteCommittee() {
|
func (suite *KeeperTestSuite) TestGetSetDeleteCommittee() {
|
||||||
// setup test
|
// setup test
|
||||||
com := types.Committee{
|
com := types.Committee{
|
||||||
ID: 12,
|
ID: 12,
|
||||||
// TODO other fields
|
Description: "This committee is for testing.",
|
||||||
|
Members: suite.addresses,
|
||||||
|
Permissions: []types.Permission{types.GodPermission{}},
|
||||||
|
VoteThreshold: d("0.667"),
|
||||||
|
MaxProposalDuration: time.Hour * 24 * 7,
|
||||||
}
|
}
|
||||||
|
|
||||||
// write and read from store
|
// write and read from store
|
||||||
@ -56,8 +64,10 @@ func (suite *KeeperTestSuite) TestGetSetDeleteCommittee() {
|
|||||||
func (suite *KeeperTestSuite) TestGetSetProposal() {
|
func (suite *KeeperTestSuite) TestGetSetProposal() {
|
||||||
// test setup
|
// test setup
|
||||||
prop := types.Proposal{
|
prop := types.Proposal{
|
||||||
ID: 12,
|
ID: 12,
|
||||||
// TODO other fields
|
CommitteeID: 0,
|
||||||
|
PubProposal: gov.NewTextProposal("A Title", "A description of this proposal."),
|
||||||
|
Deadline: time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC),
|
||||||
}
|
}
|
||||||
|
|
||||||
// write and read from store
|
// write and read from store
|
||||||
@ -81,7 +91,6 @@ func (suite *KeeperTestSuite) TestGetSetVote() {
|
|||||||
vote := types.Vote{
|
vote := types.Vote{
|
||||||
ProposalID: 12,
|
ProposalID: 12,
|
||||||
Voter: suite.addresses[0],
|
Voter: suite.addresses[0],
|
||||||
// TODO other fields
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write and read from store
|
// write and read from store
|
||||||
|
@ -30,7 +30,7 @@ func (k Keeper) SubmitProposal(ctx sdk.Context, proposer sdk.AccAddress, committ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get a new ID and store the proposal
|
// Get a new ID and store the proposal
|
||||||
deadline := ctx.BlockTime().Add(types.MaxProposalDuration)
|
deadline := ctx.BlockTime().Add(com.MaxProposalDuration)
|
||||||
proposalID, err := k.StoreNewProposal(ctx, pubProposal, committeeID, deadline)
|
proposalID, err := k.StoreNewProposal(ctx, pubProposal, committeeID, deadline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -82,7 +82,7 @@ func (k Keeper) GetProposalResult(ctx sdk.Context, proposalID uint64) (bool, sdk
|
|||||||
|
|
||||||
numVotes := k.TallyVotes(ctx, proposalID)
|
numVotes := k.TallyVotes(ctx, proposalID)
|
||||||
|
|
||||||
proposalResult := sdk.NewDec(numVotes).GTE(types.VoteThreshold.MulInt64(int64(len(com.Members))))
|
proposalResult := sdk.NewDec(numVotes).GTE(com.VoteThreshold.MulInt64(int64(len(com.Members))))
|
||||||
|
|
||||||
return proposalResult, nil
|
return proposalResult, nil
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,15 @@ import (
|
|||||||
|
|
||||||
func (suite *KeeperTestSuite) TestSubmitProposal() {
|
func (suite *KeeperTestSuite) TestSubmitProposal() {
|
||||||
normalCom := types.Committee{
|
normalCom := types.Committee{
|
||||||
ID: 12,
|
ID: 12,
|
||||||
Members: suite.addresses[:2],
|
Description: "This committee is for testing.",
|
||||||
Permissions: []types.Permission{types.GodPermission{}},
|
Members: suite.addresses[:2],
|
||||||
}
|
Permissions: []types.Permission{types.GodPermission{}},
|
||||||
noPermissionsCom := types.Committee{
|
VoteThreshold: d("0.667"),
|
||||||
ID: 12,
|
MaxProposalDuration: time.Hour * 24 * 7,
|
||||||
Members: suite.addresses[:2],
|
|
||||||
Permissions: []types.Permission{},
|
|
||||||
}
|
}
|
||||||
|
noPermissionsCom := normalCom
|
||||||
|
noPermissionsCom.Permissions = []types.Permission{}
|
||||||
|
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
name string
|
name string
|
||||||
@ -96,7 +96,7 @@ func (suite *KeeperTestSuite) TestSubmitProposal() {
|
|||||||
pr, found := keeper.GetProposal(ctx, id)
|
pr, found := keeper.GetProposal(ctx, id)
|
||||||
suite.True(found)
|
suite.True(found)
|
||||||
suite.Equal(tc.committeeID, pr.CommitteeID)
|
suite.Equal(tc.committeeID, pr.CommitteeID)
|
||||||
suite.Equal(ctx.BlockTime().Add(types.MaxProposalDuration), pr.Deadline)
|
suite.Equal(ctx.BlockTime().Add(tc.committee.MaxProposalDuration), pr.Deadline)
|
||||||
} else {
|
} else {
|
||||||
suite.NotNil(err)
|
suite.NotNil(err)
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ func (suite *KeeperTestSuite) TestAddVote() {
|
|||||||
name: "proposal expired",
|
name: "proposal expired",
|
||||||
proposalID: types.DefaultNextProposalID,
|
proposalID: types.DefaultNextProposalID,
|
||||||
voter: normalCom.Members[0],
|
voter: normalCom.Members[0],
|
||||||
voteTime: firstBlockTime.Add(types.MaxProposalDuration),
|
voteTime: firstBlockTime.Add(normalCom.MaxProposalDuration),
|
||||||
expectPass: false,
|
expectPass: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -174,6 +174,14 @@ func (suite *KeeperTestSuite) TestAddVote() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *KeeperTestSuite) TestGetProposalResult() {
|
func (suite *KeeperTestSuite) TestGetProposalResult() {
|
||||||
|
normalCom := types.Committee{
|
||||||
|
ID: 12,
|
||||||
|
Description: "This committee is for testing.",
|
||||||
|
Members: suite.addresses[:5],
|
||||||
|
Permissions: []types.Permission{types.GodPermission{}},
|
||||||
|
VoteThreshold: d("0.667"),
|
||||||
|
MaxProposalDuration: time.Hour * 24 * 7,
|
||||||
|
}
|
||||||
var defaultID uint64 = 1
|
var defaultID uint64 = 1
|
||||||
firstBlockTime := time.Date(1998, time.January, 1, 1, 0, 0, 0, time.UTC)
|
firstBlockTime := time.Date(1998, time.January, 1, 1, 0, 0, 0, time.UTC)
|
||||||
|
|
||||||
@ -185,12 +193,8 @@ func (suite *KeeperTestSuite) TestGetProposalResult() {
|
|||||||
expectPass bool
|
expectPass bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "enough votes",
|
name: "enough votes",
|
||||||
committee: types.Committee{
|
committee: normalCom,
|
||||||
ID: 12,
|
|
||||||
Members: suite.addresses[:5],
|
|
||||||
Permissions: []types.Permission{types.GodPermission{}},
|
|
||||||
},
|
|
||||||
votes: []types.Vote{
|
votes: []types.Vote{
|
||||||
{ProposalID: defaultID, Voter: suite.addresses[0]},
|
{ProposalID: defaultID, Voter: suite.addresses[0]},
|
||||||
{ProposalID: defaultID, Voter: suite.addresses[1]},
|
{ProposalID: defaultID, Voter: suite.addresses[1]},
|
||||||
@ -201,12 +205,8 @@ func (suite *KeeperTestSuite) TestGetProposalResult() {
|
|||||||
expectPass: true,
|
expectPass: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "not enough votes",
|
name: "not enough votes",
|
||||||
committee: types.Committee{
|
committee: normalCom,
|
||||||
ID: 12,
|
|
||||||
Members: suite.addresses[:5],
|
|
||||||
Permissions: []types.Permission{types.GodPermission{}},
|
|
||||||
},
|
|
||||||
votes: []types.Vote{
|
votes: []types.Vote{
|
||||||
{ProposalID: defaultID, Voter: suite.addresses[0]},
|
{ProposalID: defaultID, Voter: suite.addresses[0]},
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,7 @@ package keeper_test
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ import (
|
|||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
||||||
"github.com/kava-labs/kava/app"
|
"github.com/kava-labs/kava/app"
|
||||||
|
"github.com/kava-labs/kava/x/committee"
|
||||||
"github.com/kava-labs/kava/x/committee/keeper"
|
"github.com/kava-labs/kava/x/committee/keeper"
|
||||||
"github.com/kava-labs/kava/x/committee/types"
|
"github.com/kava-labs/kava/x/committee/types"
|
||||||
)
|
)
|
||||||
@ -20,6 +22,12 @@ const (
|
|||||||
custom = "custom"
|
custom = "custom"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var testTime time.Time = time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||||
|
|
||||||
|
func NewCommitteeGenesisState(cdc *codec.Codec, gs committee.GenesisState) app.GenesisState {
|
||||||
|
return app.GenesisState{committee.ModuleName: cdc.MustMarshalJSON(gs)}
|
||||||
|
}
|
||||||
|
|
||||||
type QuerierTestSuite struct {
|
type QuerierTestSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
|
|
||||||
@ -30,10 +38,9 @@ type QuerierTestSuite struct {
|
|||||||
|
|
||||||
querier sdk.Querier
|
querier sdk.Querier
|
||||||
|
|
||||||
addresses []sdk.AccAddress
|
addresses []sdk.AccAddress
|
||||||
committees []types.Committee
|
testGenesis types.GenesisState
|
||||||
proposals []types.Proposal
|
votes map[uint64]([]types.Vote)
|
||||||
votes map[uint64]([]types.Vote)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QuerierTestSuite) SetupTest() {
|
func (suite *QuerierTestSuite) SetupTest() {
|
||||||
@ -44,37 +51,40 @@ func (suite *QuerierTestSuite) SetupTest() {
|
|||||||
suite.querier = keeper.NewQuerier(suite.keeper)
|
suite.querier = keeper.NewQuerier(suite.keeper)
|
||||||
|
|
||||||
_, suite.addresses = app.GeneratePrivKeyAddressPairs(5)
|
_, suite.addresses = app.GeneratePrivKeyAddressPairs(5)
|
||||||
suite.app.InitializeFromGenesisStates()
|
suite.testGenesis = types.NewGenesisState(
|
||||||
// TODO replace below with genesis state
|
3,
|
||||||
normalCom := types.Committee{
|
[]types.Committee{
|
||||||
ID: 12,
|
{
|
||||||
Members: suite.addresses[:2],
|
ID: 1,
|
||||||
Permissions: []types.Permission{types.GodPermission{}},
|
Description: "This committee is for testing.",
|
||||||
}
|
Members: suite.addresses[:3],
|
||||||
suite.keeper.SetCommittee(suite.ctx, normalCom)
|
Permissions: []types.Permission{types.GodPermission{}},
|
||||||
|
VoteThreshold: d("0.667"),
|
||||||
|
MaxProposalDuration: time.Hour * 24 * 7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 2,
|
||||||
|
Members: suite.addresses[2:],
|
||||||
|
Permissions: nil,
|
||||||
|
VoteThreshold: d("0.667"),
|
||||||
|
MaxProposalDuration: time.Hour * 24 * 7,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[]types.Proposal{
|
||||||
|
{ID: 1, CommitteeID: 1, PubProposal: gov.NewTextProposal("A Title", "A description of this proposal."), Deadline: testTime.Add(7 * 24 * time.Hour)},
|
||||||
|
{ID: 2, CommitteeID: 1, PubProposal: gov.NewTextProposal("Another Title", "A description of this other proposal."), Deadline: testTime.Add(21 * 24 * time.Hour)},
|
||||||
|
},
|
||||||
|
[]types.Vote{
|
||||||
|
{ProposalID: 1, Voter: suite.addresses[0]},
|
||||||
|
{ProposalID: 1, Voter: suite.addresses[1]},
|
||||||
|
{ProposalID: 2, Voter: suite.addresses[2]},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
suite.app.InitializeFromGenesisStates(
|
||||||
|
NewCommitteeGenesisState(suite.cdc, suite.testGenesis),
|
||||||
|
)
|
||||||
|
|
||||||
pprop1 := gov.NewTextProposal("1A Title", "A description of this proposal.")
|
// Collect up votes into a map indexed by proposalID for convenience
|
||||||
id1, err := suite.keeper.SubmitProposal(suite.ctx, normalCom.Members[0], normalCom.ID, pprop1)
|
|
||||||
suite.NoError(err)
|
|
||||||
|
|
||||||
pprop2 := gov.NewTextProposal("2A Title", "A description of this proposal.")
|
|
||||||
id2, err := suite.keeper.SubmitProposal(suite.ctx, normalCom.Members[0], normalCom.ID, pprop2)
|
|
||||||
suite.NoError(err)
|
|
||||||
|
|
||||||
err = suite.keeper.AddVote(suite.ctx, id1, normalCom.Members[0])
|
|
||||||
suite.NoError(err)
|
|
||||||
err = suite.keeper.AddVote(suite.ctx, id1, normalCom.Members[1])
|
|
||||||
suite.NoError(err)
|
|
||||||
err = suite.keeper.AddVote(suite.ctx, id2, normalCom.Members[1])
|
|
||||||
suite.NoError(err)
|
|
||||||
|
|
||||||
suite.committees = []types.Committee{}
|
|
||||||
suite.committees = []types.Committee{normalCom} // TODO
|
|
||||||
suite.proposals = []types.Proposal{}
|
|
||||||
suite.keeper.IterateProposals(suite.ctx, func(p types.Proposal) bool {
|
|
||||||
suite.proposals = append(suite.proposals, p)
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
suite.votes = map[uint64]([]types.Vote){}
|
suite.votes = map[uint64]([]types.Vote){}
|
||||||
suite.keeper.IterateProposals(suite.ctx, func(p types.Proposal) bool {
|
suite.keeper.IterateProposals(suite.ctx, func(p types.Proposal) bool {
|
||||||
suite.keeper.IterateVotes(suite.ctx, p.ID, func(v types.Vote) bool {
|
suite.keeper.IterateVotes(suite.ctx, p.ID, func(v types.Vote) bool {
|
||||||
@ -102,7 +112,7 @@ func (suite *QuerierTestSuite) TestQueryCommittees() {
|
|||||||
suite.NoError(suite.cdc.UnmarshalJSON(bz, &committees))
|
suite.NoError(suite.cdc.UnmarshalJSON(bz, &committees))
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
suite.Equal(suite.committees, committees)
|
suite.Equal(suite.testGenesis.Committees, committees)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QuerierTestSuite) TestQueryCommittee() {
|
func (suite *QuerierTestSuite) TestQueryCommittee() {
|
||||||
@ -110,7 +120,7 @@ func (suite *QuerierTestSuite) TestQueryCommittee() {
|
|||||||
// Set up request query
|
// Set up request query
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryCommittee}, "/"),
|
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryCommittee}, "/"),
|
||||||
Data: suite.cdc.MustMarshalJSON(types.NewQueryCommitteeParams(suite.committees[0].ID)),
|
Data: suite.cdc.MustMarshalJSON(types.NewQueryCommitteeParams(suite.testGenesis.Committees[0].ID)),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute query and check the []byte result
|
// Execute query and check the []byte result
|
||||||
@ -123,13 +133,13 @@ func (suite *QuerierTestSuite) TestQueryCommittee() {
|
|||||||
suite.NoError(suite.cdc.UnmarshalJSON(bz, &committee))
|
suite.NoError(suite.cdc.UnmarshalJSON(bz, &committee))
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
suite.Equal(suite.committees[0], committee)
|
suite.Equal(suite.testGenesis.Committees[0], committee)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QuerierTestSuite) TestQueryProposals() {
|
func (suite *QuerierTestSuite) TestQueryProposals() {
|
||||||
ctx := suite.ctx.WithIsCheckTx(false)
|
ctx := suite.ctx.WithIsCheckTx(false)
|
||||||
// Set up request query
|
// Set up request query
|
||||||
comID := suite.proposals[0].CommitteeID
|
comID := suite.testGenesis.Proposals[0].CommitteeID
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryProposals}, "/"),
|
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryProposals}, "/"),
|
||||||
Data: suite.cdc.MustMarshalJSON(types.NewQueryCommitteeParams(comID)),
|
Data: suite.cdc.MustMarshalJSON(types.NewQueryCommitteeParams(comID)),
|
||||||
@ -146,7 +156,7 @@ func (suite *QuerierTestSuite) TestQueryProposals() {
|
|||||||
|
|
||||||
// Check
|
// Check
|
||||||
expectedProposals := []types.Proposal{}
|
expectedProposals := []types.Proposal{}
|
||||||
for _, p := range suite.proposals {
|
for _, p := range suite.testGenesis.Proposals {
|
||||||
if p.CommitteeID == comID {
|
if p.CommitteeID == comID {
|
||||||
expectedProposals = append(expectedProposals, p)
|
expectedProposals = append(expectedProposals, p)
|
||||||
}
|
}
|
||||||
@ -159,7 +169,7 @@ func (suite *QuerierTestSuite) TestQueryProposal() {
|
|||||||
// Set up request query
|
// Set up request query
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryProposal}, "/"),
|
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryProposal}, "/"),
|
||||||
Data: suite.cdc.MustMarshalJSON(types.NewQueryProposalParams(suite.proposals[0].ID)),
|
Data: suite.cdc.MustMarshalJSON(types.NewQueryProposalParams(suite.testGenesis.Proposals[0].ID)),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute query and check the []byte result
|
// Execute query and check the []byte result
|
||||||
@ -172,13 +182,13 @@ func (suite *QuerierTestSuite) TestQueryProposal() {
|
|||||||
suite.NoError(suite.cdc.UnmarshalJSON(bz, &proposal))
|
suite.NoError(suite.cdc.UnmarshalJSON(bz, &proposal))
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
suite.Equal(suite.proposals[0], proposal)
|
suite.Equal(suite.testGenesis.Proposals[0], proposal)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QuerierTestSuite) TestQueryVotes() {
|
func (suite *QuerierTestSuite) TestQueryVotes() {
|
||||||
ctx := suite.ctx.WithIsCheckTx(false)
|
ctx := suite.ctx.WithIsCheckTx(false)
|
||||||
// Set up request query
|
// Set up request query
|
||||||
propID := suite.proposals[0].ID
|
propID := suite.testGenesis.Proposals[0].ID
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryVotes}, "/"),
|
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryVotes}, "/"),
|
||||||
Data: suite.cdc.MustMarshalJSON(types.NewQueryProposalParams(propID)),
|
Data: suite.cdc.MustMarshalJSON(types.NewQueryProposalParams(propID)),
|
||||||
@ -200,7 +210,7 @@ func (suite *QuerierTestSuite) TestQueryVotes() {
|
|||||||
func (suite *QuerierTestSuite) TestQueryVote() {
|
func (suite *QuerierTestSuite) TestQueryVote() {
|
||||||
ctx := suite.ctx.WithIsCheckTx(false) // ?
|
ctx := suite.ctx.WithIsCheckTx(false) // ?
|
||||||
// Set up request query
|
// Set up request query
|
||||||
propID := suite.proposals[0].ID
|
propID := suite.testGenesis.Proposals[0].ID
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryVote}, "/"),
|
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryVote}, "/"),
|
||||||
Data: suite.cdc.MustMarshalJSON(types.NewQueryVoteParams(propID, suite.votes[propID][0].Voter)),
|
Data: suite.cdc.MustMarshalJSON(types.NewQueryVoteParams(propID, suite.votes[propID][0].Voter)),
|
||||||
@ -222,7 +232,7 @@ func (suite *QuerierTestSuite) TestQueryVote() {
|
|||||||
func (suite *QuerierTestSuite) TestQueryTally() {
|
func (suite *QuerierTestSuite) TestQueryTally() {
|
||||||
ctx := suite.ctx.WithIsCheckTx(false) // ?
|
ctx := suite.ctx.WithIsCheckTx(false) // ?
|
||||||
// Set up request query
|
// Set up request query
|
||||||
propID := suite.proposals[0].ID
|
propID := suite.testGenesis.Proposals[0].ID
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryTally}, "/"),
|
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryTally}, "/"),
|
||||||
Data: suite.cdc.MustMarshalJSON(types.NewQueryProposalParams(propID)),
|
Data: suite.cdc.MustMarshalJSON(types.NewQueryProposalParams(propID)),
|
||||||
|
@ -38,14 +38,19 @@ func (suite *ProposalHandlerTestSuite) SetupTest() {
|
|||||||
2,
|
2,
|
||||||
[]committee.Committee{
|
[]committee.Committee{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Members: suite.addresses[:3],
|
Description: "This committee is for testing.",
|
||||||
Permissions: []types.Permission{types.GodPermission{}},
|
Members: suite.addresses[:3],
|
||||||
|
Permissions: []types.Permission{types.GodPermission{}},
|
||||||
|
VoteThreshold: d("0.667"),
|
||||||
|
MaxProposalDuration: time.Hour * 24 * 7,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 2,
|
ID: 2,
|
||||||
Members: suite.addresses[2:],
|
Members: suite.addresses[2:],
|
||||||
Permissions: nil,
|
Permissions: nil,
|
||||||
|
VoteThreshold: d("0.667"),
|
||||||
|
MaxProposalDuration: time.Hour * 24 * 7,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[]committee.Proposal{
|
[]committee.Proposal{
|
||||||
@ -69,8 +74,10 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_ChangeCommittee() {
|
|||||||
"A Title",
|
"A Title",
|
||||||
"A proposal description.",
|
"A proposal description.",
|
||||||
committee.Committee{
|
committee.Committee{
|
||||||
ID: 34,
|
ID: 34,
|
||||||
Members: suite.addresses[:1],
|
Members: suite.addresses[:1],
|
||||||
|
VoteThreshold: d("1"),
|
||||||
|
MaxProposalDuration: time.Hour * 24,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
expectPass: true,
|
expectPass: true,
|
||||||
@ -81,9 +88,11 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_ChangeCommittee() {
|
|||||||
"A Title",
|
"A Title",
|
||||||
"A proposal description.",
|
"A proposal description.",
|
||||||
committee.Committee{
|
committee.Committee{
|
||||||
ID: 1,
|
ID: suite.testGenesis.Committees[0].ID,
|
||||||
Members: suite.addresses,
|
Members: suite.addresses, // add new members
|
||||||
Permissions: suite.testGenesis.Committees[0].Permissions,
|
Permissions: suite.testGenesis.Committees[0].Permissions,
|
||||||
|
VoteThreshold: suite.testGenesis.Committees[0].VoteThreshold,
|
||||||
|
MaxProposalDuration: suite.testGenesis.Committees[0].MaxProposalDuration,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
expectPass: true,
|
expectPass: true,
|
||||||
@ -93,9 +102,7 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_ChangeCommittee() {
|
|||||||
proposal: committee.NewCommitteeChangeProposal(
|
proposal: committee.NewCommitteeChangeProposal(
|
||||||
"A Title That Is Much Too Long And Really Quite Unreasonable Given That It Is Trying To Fullfill The Roll Of An Acceptable Governance Proposal Title That Should Succinctly Communicate The Goal And Contents Of The Proposed Proposal To All Parties Involved",
|
"A Title That Is Much Too Long And Really Quite Unreasonable Given That It Is Trying To Fullfill The Roll Of An Acceptable Governance Proposal Title That Should Succinctly Communicate The Goal And Contents Of The Proposed Proposal To All Parties Involved",
|
||||||
"A proposal description.",
|
"A proposal description.",
|
||||||
committee.Committee{
|
suite.testGenesis.Committees[0],
|
||||||
ID: 34,
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
expectPass: false,
|
expectPass: false,
|
||||||
},
|
},
|
||||||
@ -105,9 +112,11 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_ChangeCommittee() {
|
|||||||
"A Title",
|
"A Title",
|
||||||
"A proposal description.",
|
"A proposal description.",
|
||||||
committee.Committee{
|
committee.Committee{
|
||||||
ID: 1,
|
ID: suite.testGenesis.Committees[0].ID,
|
||||||
Members: append(suite.addresses, suite.addresses[0]), // duplicate address
|
Members: append(suite.addresses, suite.addresses[0]), // duplicate address
|
||||||
Permissions: suite.testGenesis.Committees[0].Permissions,
|
Permissions: suite.testGenesis.Committees[0].Permissions,
|
||||||
|
VoteThreshold: suite.testGenesis.Committees[0].VoteThreshold,
|
||||||
|
MaxProposalDuration: suite.testGenesis.Committees[0].MaxProposalDuration,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
expectPass: false,
|
expectPass: false,
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/tendermint/tendermint/crypto"
|
"github.com/tendermint/tendermint/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func d(s string) sdk.Dec { return sdk.MustNewDecFromStr(s) }
|
||||||
func TestGenesisState_Validate(t *testing.T) {
|
func TestGenesisState_Validate(t *testing.T) {
|
||||||
testTime := time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC)
|
testTime := time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||||
addresses := []sdk.AccAddress{
|
addresses := []sdk.AccAddress{
|
||||||
@ -24,14 +25,20 @@ func TestGenesisState_Validate(t *testing.T) {
|
|||||||
NextProposalID: 2,
|
NextProposalID: 2,
|
||||||
Committees: []Committee{
|
Committees: []Committee{
|
||||||
{
|
{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Members: addresses[:3],
|
Description: "This committee is for testing.",
|
||||||
Permissions: []Permission{GodPermission{}},
|
Members: addresses[:3],
|
||||||
|
Permissions: []Permission{GodPermission{}},
|
||||||
|
VoteThreshold: d("0.667"),
|
||||||
|
MaxProposalDuration: time.Hour * 24 * 7,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 2,
|
ID: 2,
|
||||||
Members: addresses[2:],
|
Description: "This committee is also for testing.",
|
||||||
Permissions: nil,
|
Members: addresses[2:],
|
||||||
|
Permissions: nil,
|
||||||
|
VoteThreshold: d("0.8"),
|
||||||
|
MaxProposalDuration: time.Hour * 24 * 21,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Proposals: []Proposal{
|
Proposals: []Proposal{
|
||||||
|
@ -16,6 +16,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GodPermission allows any governance proposal. It is used mainly for testing.
|
// GodPermission allows any governance proposal. It is used mainly for testing.
|
||||||
|
// TODO better name?
|
||||||
type GodPermission struct{}
|
type GodPermission struct{}
|
||||||
|
|
||||||
var _ Permission = GodPermission{}
|
var _ Permission = GodPermission{}
|
||||||
|
@ -9,29 +9,28 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO move these into params
|
const MaxCommitteeDescriptionLength int = 5000
|
||||||
var (
|
|
||||||
VoteThreshold sdk.Dec = sdk.MustNewDecFromStr("0.75")
|
|
||||||
MaxProposalDuration time.Duration = time.Hour * 24 * 7
|
|
||||||
)
|
|
||||||
|
|
||||||
// -------- Committees --------
|
// -------- Committees --------
|
||||||
|
|
||||||
// A Committee is a collection of addresses that are allowed to vote and enact any governance proposal that passes their permissions.
|
// A Committee is a collection of addresses that are allowed to vote and enact any governance proposal that passes their permissions.
|
||||||
type Committee struct {
|
type Committee struct {
|
||||||
ID uint64 `json:"id" yaml:"id"`
|
ID uint64 `json:"id" yaml:"id"`
|
||||||
//Description string `json:"description" yaml:"description"`
|
Description string `json:"description" yaml:"description"`
|
||||||
Members []sdk.AccAddress `json:"members" yaml:"members"`
|
Members []sdk.AccAddress `json:"members" yaml:"members"`
|
||||||
Permissions []Permission `json:"permissions" yaml:"permissions"`
|
Permissions []Permission `json:"permissions" yaml:"permissions"`
|
||||||
// VoteThreshold sdk.Dec `json:"vote_threshold" yaml:"vote_threshold"`
|
VoteThreshold sdk.Dec `json:"vote_threshold" yaml:"vote_threshold"`
|
||||||
// MaxProposalDuration time.Duration `json:"max_proposal_duration" yaml:"max_proposal_duration"`
|
MaxProposalDuration time.Duration `json:"max_proposal_duration" yaml:"max_proposal_duration"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCommittee(id uint64, members []sdk.AccAddress, permissions []Permission) Committee {
|
func NewCommittee(id uint64, description string, members []sdk.AccAddress, permissions []Permission, threshold sdk.Dec, duration time.Duration) Committee {
|
||||||
return Committee{
|
return Committee{
|
||||||
ID: id,
|
ID: id,
|
||||||
Members: members,
|
Description: description,
|
||||||
Permissions: permissions,
|
Members: members,
|
||||||
|
Permissions: permissions,
|
||||||
|
VoteThreshold: threshold,
|
||||||
|
MaxProposalDuration: duration,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +73,19 @@ func (c Committee) Validate() error {
|
|||||||
if len(c.Members) == 0 {
|
if len(c.Members) == 0 {
|
||||||
return fmt.Errorf("committee %d invalid: cannot have zero members", c.ID)
|
return fmt.Errorf("committee %d invalid: cannot have zero members", c.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(c.Description) > MaxCommitteeDescriptionLength {
|
||||||
|
return fmt.Errorf("invalid description")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.VoteThreshold.IsNil() || c.VoteThreshold.IsNegative() || c.VoteThreshold.GT(sdk.NewDec(1)) {
|
||||||
|
return fmt.Errorf("invalid threshold")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.MaxProposalDuration < 0 {
|
||||||
|
return fmt.Errorf("invalid time")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,5 +130,4 @@ func (p Proposal) String() string {
|
|||||||
type Vote struct {
|
type Vote struct {
|
||||||
ProposalID uint64 `json:"proposal_id" yaml:"proposal_id"`
|
ProposalID uint64 `json:"proposal_id" yaml:"proposal_id"`
|
||||||
Voter sdk.AccAddress `json:"voter" yaml:"voter"`
|
Voter sdk.AccAddress `json:"voter" yaml:"voter"`
|
||||||
// Option byte // TODO for now don't need more than just a yes as options
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user