address various pr comments

This commit is contained in:
rhuairahrighairigh 2020-04-25 00:22:56 +01:00
parent ccad1f82e2
commit ebb6366837
10 changed files with 120 additions and 110 deletions

View File

@ -37,11 +37,11 @@ func (suite *ModuleTestSuite) TestBeginBlock() {
suite.app.InitializeFromGenesisStates() suite.app.InitializeFromGenesisStates()
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"), VoteThreshold: d("0.8"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: time.Hour * 24 * 7,
} }
suite.keeper.SetCommittee(suite.ctx, normalCom) suite.keeper.SetCommittee(suite.ctx, normalCom)
@ -55,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(normalCom.MaxProposalDuration)) proposalDurationLaterCtx := suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(normalCom.ProposalDuration))
suite.NotPanics(func() { suite.NotPanics(func() {
committee.BeginBlocker(proposalDurationLaterCtx, abci.RequestBeginBlock{}, suite.keeper) committee.BeginBlocker(proposalDurationLaterCtx, abci.RequestBeginBlock{}, suite.keeper)
}) })

View File

@ -10,7 +10,6 @@ import (
const ( const (
RestProposalID = "proposal-id" RestProposalID = "proposal-id"
RestCommitteeID = "committee-id" RestCommitteeID = "committee-id"
RestVoter = "voter"
) )
// RegisterRoutes - Central function to define routes that get registered by the main application // RegisterRoutes - Central function to define routes that get registered by the main application

View File

@ -2,16 +2,18 @@ package keeper_test
import ( import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/committee/keeper"
"github.com/kava-labs/kava/x/committee/types" "github.com/kava-labs/kava/x/committee/types"
) )
// proposalVoteMap collects up votes into a map indexed by proposalID // proposalVoteMap collects up votes into a map indexed by proposalID
func getProposalVoteMap(k keeper.Keeper, ctx sdk.Context) map[uint64]([]types.Vote) { func getProposalVoteMap(k keeper.Keeper, ctx sdk.Context) map[uint64]([]types.Vote) {
proposalVoteMap = map[uint64]([]types.Vote){} proposalVoteMap := map[uint64]([]types.Vote){}
keeper.IterateProposals(suite.ctx, func(p types.Proposal) bool { k.IterateProposals(ctx, func(p types.Proposal) bool {
keeper.IterateVotes(suite.ctx, p.ID, func(v types.Vote) bool { k.IterateVotes(ctx, p.ID, func(v types.Vote) bool {
proposalVoteMap[p.ID] = append(proposalVoteMap[p.ID], v) proposalVoteMap[p.ID] = append(proposalVoteMap[p.ID], v)
return false return false
}) })

View File

@ -37,12 +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,
Description: "This committee is for testing.", Description: "This committee is for testing.",
Members: suite.addresses, Members: suite.addresses,
Permissions: []types.Permission{types.GodPermission{}}, Permissions: []types.Permission{types.GodPermission{}},
VoteThreshold: d("0.667"), VoteThreshold: d("0.667"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: time.Hour * 24 * 7,
} }
// write and read from store // write and read from store

View File

@ -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(com.MaxProposalDuration) deadline := ctx.BlockTime().Add(com.ProposalDuration)
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

View File

@ -17,12 +17,12 @@ import (
func (suite *KeeperTestSuite) TestSubmitProposal() { func (suite *KeeperTestSuite) TestSubmitProposal() {
normalCom := types.Committee{ normalCom := types.Committee{
ID: 12, ID: 12,
Description: "This committee is for testing.", Description: "This committee is for testing.",
Members: suite.addresses[:2], Members: suite.addresses[:2],
Permissions: []types.Permission{types.GodPermission{}}, Permissions: []types.Permission{types.GodPermission{}},
VoteThreshold: d("0.667"), VoteThreshold: d("0.667"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: time.Hour * 24 * 7,
} }
noPermissionsCom := normalCom noPermissionsCom := normalCom
noPermissionsCom.Permissions = []types.Permission{} noPermissionsCom.Permissions = []types.Permission{}
@ -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(tc.committee.MaxProposalDuration), pr.Deadline) suite.Equal(ctx.BlockTime().Add(tc.committee.ProposalDuration), 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(normalCom.MaxProposalDuration), voteTime: firstBlockTime.Add(normalCom.ProposalDuration),
expectPass: false, expectPass: false,
}, },
} }
@ -175,12 +175,12 @@ func (suite *KeeperTestSuite) TestAddVote() {
func (suite *KeeperTestSuite) TestGetProposalResult() { func (suite *KeeperTestSuite) TestGetProposalResult() {
normalCom := types.Committee{ normalCom := types.Committee{
ID: 12, ID: 12,
Description: "This committee is for testing.", Description: "This committee is for testing.",
Members: suite.addresses[:5], Members: suite.addresses[:5],
Permissions: []types.Permission{types.GodPermission{}}, Permissions: []types.Permission{types.GodPermission{}},
VoteThreshold: d("0.667"), VoteThreshold: d("0.667"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: 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)
@ -327,23 +327,23 @@ func (suite *KeeperTestSuite) TestCloseExpiredProposals() {
// Setup test state // Setup test state
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)
testGenesis = types.NewGenesisState( testGenesis := types.NewGenesisState(
3, 3,
[]types.Committee{ []types.Committee{
{ {
ID: 1, ID: 1,
Description: "This committee is for testing.", Description: "This committee is for testing.",
Members: suite.addresses[:3], Members: suite.addresses[:3],
Permissions: []types.Permission{types.GodPermission{}}, Permissions: []types.Permission{types.GodPermission{}},
VoteThreshold: d("0.667"), VoteThreshold: d("0.667"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: time.Hour * 24 * 7,
}, },
{ {
ID: 2, ID: 2,
Members: suite.addresses[2:], Members: suite.addresses[2:],
Permissions: nil, Permissions: nil,
VoteThreshold: d("0.667"), VoteThreshold: d("0.667"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: time.Hour * 24 * 7,
}, },
}, },
[]types.Proposal{ []types.Proposal{
@ -367,16 +367,16 @@ func (suite *KeeperTestSuite) TestCloseExpiredProposals() {
}, },
) )
suite.app.InitializeFromGenesisStates( suite.app.InitializeFromGenesisStates(
NewCommitteeGenesisState(suite.cdc, testGenesis), NewCommitteeGenesisState(suite.app.Codec(), testGenesis),
) )
// close proposals // close proposals
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: firstBlockTime}) ctx := suite.app.NewContext(true, abci.Header{Height: 1, Time: firstBlockTime})
suite.keeper.CloseExpiredProposals(ctx) suite.keeper.CloseExpiredProposals(ctx)
// check // check
for _, p := range testGenesis.Proposals { for _, p := range testGenesis.Proposals {
_, found := k.GetProposal(ctx, p.ID) _, found := suite.keeper.GetProposal(ctx, p.ID)
votes := getProposalVoteMap(suite.keeper, ctx) votes := getProposalVoteMap(suite.keeper, ctx)
if ctx.BlockTime().After(p.Deadline) { if ctx.BlockTime().After(p.Deadline) {
@ -389,15 +389,15 @@ func (suite *KeeperTestSuite) TestCloseExpiredProposals() {
} }
// close (later time) // close (later time)
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: firstBlockTime.Add(7 * 24 * time.Hour)}) ctx = suite.app.NewContext(true, abci.Header{Height: 1, Time: firstBlockTime.Add(7 * 24 * time.Hour)})
suite.keeper.CloseExpiredProposals(ctx) suite.keeper.CloseExpiredProposals(ctx)
// check // check
for _, p := range testGenesis.Proposals { for _, p := range testGenesis.Proposals {
_, found := k.GetProposal(ctx, p.ID) _, found := suite.keeper.GetProposal(ctx, p.ID)
votes := getProposalVoteMap(suite.keeper, ctx) votes := getProposalVoteMap(suite.keeper, ctx)
if ctx.BlockTime().After(p.Deadline) { if ctx.BlockTime().Equal(p.Deadline) || ctx.BlockTime().After(p.Deadline) {
suite.False(found) suite.False(found)
suite.Empty(votes[p.ID]) suite.Empty(votes[p.ID])
} else { } else {

View File

@ -55,19 +55,19 @@ func (suite *QuerierTestSuite) SetupTest() {
3, 3,
[]types.Committee{ []types.Committee{
{ {
ID: 1, ID: 1,
Description: "This committee is for testing.", Description: "This committee is for testing.",
Members: suite.addresses[:3], Members: suite.addresses[:3],
Permissions: []types.Permission{types.GodPermission{}}, Permissions: []types.Permission{types.GodPermission{}},
VoteThreshold: d("0.667"), VoteThreshold: d("0.667"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: time.Hour * 24 * 7,
}, },
{ {
ID: 2, ID: 2,
Members: suite.addresses[2:], Members: suite.addresses[2:],
Permissions: nil, Permissions: nil,
VoteThreshold: d("0.667"), VoteThreshold: d("0.667"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: time.Hour * 24 * 7,
}, },
}, },
[]types.Proposal{ []types.Proposal{

View File

@ -38,19 +38,19 @@ func (suite *ProposalHandlerTestSuite) SetupTest() {
2, 2,
[]committee.Committee{ []committee.Committee{
{ {
ID: 1, ID: 1,
Description: "This committee is for testing.", Description: "This committee is for testing.",
Members: suite.addresses[:3], Members: suite.addresses[:3],
Permissions: []types.Permission{types.GodPermission{}}, Permissions: []types.Permission{types.GodPermission{}},
VoteThreshold: d("0.667"), VoteThreshold: d("0.667"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: time.Hour * 24 * 7,
}, },
{ {
ID: 2, ID: 2,
Members: suite.addresses[2:], Members: suite.addresses[2:],
Permissions: nil, Permissions: nil,
VoteThreshold: d("0.667"), VoteThreshold: d("0.667"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: time.Hour * 24 * 7,
}, },
}, },
[]committee.Proposal{ []committee.Proposal{
@ -74,10 +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"), VoteThreshold: d("1"),
MaxProposalDuration: time.Hour * 24, ProposalDuration: time.Hour * 24,
}, },
), ),
expectPass: true, expectPass: true,
@ -88,11 +88,11 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_ChangeCommittee() {
"A Title", "A Title",
"A proposal description.", "A proposal description.",
committee.Committee{ committee.Committee{
ID: suite.testGenesis.Committees[0].ID, ID: suite.testGenesis.Committees[0].ID,
Members: suite.addresses, // add new members Members: suite.addresses, // add new members
Permissions: suite.testGenesis.Committees[0].Permissions, Permissions: suite.testGenesis.Committees[0].Permissions,
VoteThreshold: suite.testGenesis.Committees[0].VoteThreshold, VoteThreshold: suite.testGenesis.Committees[0].VoteThreshold,
MaxProposalDuration: suite.testGenesis.Committees[0].MaxProposalDuration, ProposalDuration: suite.testGenesis.Committees[0].ProposalDuration,
}, },
), ),
expectPass: true, expectPass: true,
@ -112,11 +112,11 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_ChangeCommittee() {
"A Title", "A Title",
"A proposal description.", "A proposal description.",
committee.Committee{ committee.Committee{
ID: suite.testGenesis.Committees[0].ID, 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, VoteThreshold: suite.testGenesis.Committees[0].VoteThreshold,
MaxProposalDuration: suite.testGenesis.Committees[0].MaxProposalDuration, ProposalDuration: suite.testGenesis.Committees[0].ProposalDuration,
}, },
), ),
expectPass: false, expectPass: false,

View File

@ -25,20 +25,20 @@ func TestGenesisState_Validate(t *testing.T) {
NextProposalID: 2, NextProposalID: 2,
Committees: []Committee{ Committees: []Committee{
{ {
ID: 1, ID: 1,
Description: "This committee is for testing.", Description: "This committee is for testing.",
Members: addresses[:3], Members: addresses[:3],
Permissions: []Permission{GodPermission{}}, Permissions: []Permission{GodPermission{}},
VoteThreshold: d("0.667"), VoteThreshold: d("0.667"),
MaxProposalDuration: time.Hour * 24 * 7, ProposalDuration: time.Hour * 24 * 7,
}, },
{ {
ID: 2, ID: 2,
Description: "This committee is also for testing.", Description: "This committee is also for testing.",
Members: addresses[2:], Members: addresses[2:],
Permissions: nil, Permissions: nil,
VoteThreshold: d("0.8"), VoteThreshold: d("0.8"),
MaxProposalDuration: time.Hour * 24 * 21, ProposalDuration: time.Hour * 24 * 21,
}, },
}, },
Proposals: []Proposal{ Proposals: []Proposal{

View File

@ -17,22 +17,22 @@ const MaxCommitteeDescriptionLength int = 5000
// 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"` ProposalDuration time.Duration `json:"proposal_duration" yaml:"proposal_duration"`
} }
func NewCommittee(id uint64, description string, members []sdk.AccAddress, permissions []Permission, threshold sdk.Dec, duration time.Duration) 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,
Description: description, Description: description,
Members: members, Members: members,
Permissions: permissions, Permissions: permissions,
VoteThreshold: threshold, VoteThreshold: threshold,
MaxProposalDuration: duration, ProposalDuration: duration,
} }
} }
@ -84,7 +84,7 @@ func (c Committee) Validate() error {
return fmt.Errorf("invalid threshold") return fmt.Errorf("invalid threshold")
} }
if c.MaxProposalDuration < 0 { if c.ProposalDuration < 0 {
return fmt.Errorf("invalid time") return fmt.Errorf("invalid time")
} }
@ -110,6 +110,15 @@ type Proposal struct {
Deadline time.Time `json:"deadline" yaml:"deadline"` Deadline time.Time `json:"deadline" yaml:"deadline"`
} }
func NewProposal(pubProposal PubProposal, id uint64, committeeID uint64, deadline time.Time) Proposal {
return Proposal{
PubProposal: pubProposal,
ID: id,
CommitteeID: committeeID,
Deadline: deadline,
}
}
// HasExpiredBy calculates if the proposal will have expired by a certain time. // HasExpiredBy calculates if the proposal will have expired by a certain time.
// All votes must be cast before deadline, those cast at time == deadline are not valid // All votes must be cast before deadline, those cast at time == deadline are not valid
func (p Proposal) HasExpiredBy(time time.Time) bool { func (p Proposal) HasExpiredBy(time time.Time) bool {