add nicer keeper get methods

This commit is contained in:
rhuairahrighairigh 2020-04-27 15:04:47 +01:00
parent 20c02a6a54
commit c17de631d2
8 changed files with 110 additions and 131 deletions

View File

@ -33,21 +33,9 @@ func ExportGenesis(ctx sdk.Context, keeper Keeper) GenesisState {
if err != nil {
panic(err)
}
committees := []types.Committee{}
keeper.IterateCommittees(ctx, func(com types.Committee) bool {
committees = append(committees, com)
return false
})
proposals := []types.Proposal{}
votes := []types.Vote{}
keeper.IterateProposals(ctx, func(p types.Proposal) bool {
proposals = append(proposals, p)
keeper.IterateVotes(ctx, p.ID, func(v types.Vote) bool {
votes = append(votes, v)
return false
})
return false
})
committees := keeper.GetCommittees(ctx)
proposals := keeper.GetProposals(ctx)
votes := keeper.GetVotes(ctx)
return types.NewGenesisState(
nextID,

View File

@ -89,6 +89,7 @@ func (suite *HandlerTestSuite) TestSubmitProposalMsg_Valid() {
}
func (suite *HandlerTestSuite) TestSubmitProposalMsg_Invalid() {
var committeeID uint64 = 1
msg := types.NewMsgSubmitProposal(
params.NewParameterChangeProposal(
"A Title",
@ -100,32 +101,34 @@ func (suite *HandlerTestSuite) TestSubmitProposalMsg_Invalid() {
}},
),
suite.addresses[0],
1,
committeeID,
)
res := suite.handler(suite.ctx, msg)
suite.False(res.IsOK())
suite.keeper.IterateProposals(suite.ctx, func(p types.Proposal) bool {
suite.Fail("proposal found when none should exist")
return true
})
suite.Empty(
suite.keeper.GetProposalsByCommittee(suite.ctx, committeeID),
"proposal found when none should exist",
)
}
func (suite *HandlerTestSuite) TestSubmitProposalMsg_Unregistered() {
var committeeID uint64 = 1
msg := types.NewMsgSubmitProposal(
UnregisteredPubProposal{},
suite.addresses[0],
1,
committeeID,
)
res := suite.handler(suite.ctx, msg)
suite.False(res.IsOK())
suite.keeper.IterateProposals(suite.ctx, func(p types.Proposal) bool {
suite.Fail("proposal found when none should exist")
return true
})
suite.Empty(
suite.keeper.GetProposalsByCommittee(suite.ctx, committeeID),
"proposal found when none should exist",
)
}
func (suite *HandlerTestSuite) TestMsgAddVote_ProposalPass() {
@ -159,10 +162,10 @@ func (suite *HandlerTestSuite) TestMsgAddVote_ProposalPass() {
// Check proposal and votes are gone
_, found := suite.keeper.GetProposal(suite.ctx, proposalID)
suite.False(found)
suite.keeper.IterateVotes(suite.ctx, proposalID, func(v types.Vote) bool {
suite.Fail("vote found when there should be none")
return true
})
suite.Empty(
suite.keeper.GetVotesByProposal(suite.ctx, proposalID),
"vote found when there should be none",
)
}
func (suite *HandlerTestSuite) TestMsgAddVote_ProposalFail() {
@ -196,10 +199,10 @@ func (suite *HandlerTestSuite) TestMsgAddVote_ProposalFail() {
// Check proposal and votes are gone
_, found := suite.keeper.GetProposal(suite.ctx, proposalID)
suite.False(found)
suite.keeper.IterateVotes(suite.ctx, proposalID, func(v types.Vote) bool {
suite.Fail("vote found when there should be none")
return true
})
suite.Empty(
suite.keeper.GetVotesByProposal(suite.ctx, proposalID),
"vote found when there should be none",
)
}
func TestHandlerTestSuite(t *testing.T) {

View File

@ -16,16 +16,13 @@ func d(str string) sdk.Dec { return sdk.MustNewDecFromStr(str)
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
// proposalVoteMap collects up votes into a map indexed by proposalID
// getProposalVoteMap collects up votes into a map indexed by proposalID
func getProposalVoteMap(k keeper.Keeper, ctx sdk.Context) map[uint64]([]types.Vote) {
proposalVoteMap := map[uint64]([]types.Vote){}
k.IterateProposals(ctx, func(p types.Proposal) bool {
k.IterateVotes(ctx, p.ID, func(v types.Vote) bool {
proposalVoteMap[p.ID] = append(proposalVoteMap[p.ID], v)
return false
})
proposalVoteMap[p.ID] = k.GetVotesByProposal(ctx, p.ID)
return false
})
return proposalVoteMap

View File

@ -78,6 +78,16 @@ func (k Keeper) IterateCommittees(ctx sdk.Context, cb func(committee types.Commi
}
}
// GetCommittees returns all stored committees.
func (k Keeper) GetCommittees(ctx sdk.Context) []types.Committee {
results := []types.Committee{}
k.IterateCommittees(ctx, func(com types.Committee) bool {
results = append(results, com)
return false
})
return results
}
// ------------------------------------------
// Proposals
// ------------------------------------------
@ -171,6 +181,39 @@ func (k Keeper) IterateProposals(ctx sdk.Context, cb func(proposal types.Proposa
}
}
// GetProposals returns all stored proposals.
func (k Keeper) GetProposals(ctx sdk.Context) []types.Proposal {
results := []types.Proposal{}
k.IterateProposals(ctx, func(prop types.Proposal) bool {
results = append(results, prop)
return false
})
return results
}
// GetProposalsByCommittee returns all proposals for one committee.
func (k Keeper) GetProposalsByCommittee(ctx sdk.Context, committeeID uint64) []types.Proposal {
results := []types.Proposal{}
k.IterateProposals(ctx, func(prop types.Proposal) bool {
if prop.CommitteeID == committeeID {
results = append(results, prop)
}
return false
})
return results
}
// DeleteProposalAndVotes removes a proposal and its associated votes.
func (k Keeper) DeleteProposalAndVotes(ctx sdk.Context, proposalID uint64) {
votes := k.GetVotesByProposal(ctx, proposalID)
k.DeleteProposal(ctx, proposalID)
for _, v := range votes {
k.DeleteVote(ctx, v.ProposalID, v.Voter)
}
}
// ------------------------------------------
// Votes
// ------------------------------------------
@ -200,11 +243,10 @@ func (k Keeper) DeleteVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddr
store.Delete(types.GetVoteKey(proposalID, voter))
}
// IterateVotes provides an iterator over all stored votes for a given proposal.
// IterateVotes provides an iterator over all stored votes.
// For each vote, cb will be called. If cb returns true, the iterator will close and stop.
func (k Keeper) IterateVotes(ctx sdk.Context, proposalID uint64, cb func(vote types.Vote) (stop bool)) {
// iterate over the section of the votes store that has all votes for a particular proposal
iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), append(types.VoteKeyPrefix, types.GetKeyFromID(proposalID)...))
func (k Keeper) IterateVotes(ctx sdk.Context, cb func(vote types.Vote) (stop bool)) {
iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), types.VoteKeyPrefix)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
@ -216,3 +258,25 @@ func (k Keeper) IterateVotes(ctx sdk.Context, proposalID uint64, cb func(vote ty
}
}
}
// GetVotes returns all stored votes.
func (k Keeper) GetVotes(ctx sdk.Context) []types.Vote {
results := []types.Vote{}
k.IterateVotes(ctx, func(vote types.Vote) bool {
results = append(results, vote)
return false
})
return results
}
// GetVotesByProposal returns all votes for one proposal.
func (k Keeper) GetVotesByProposal(ctx sdk.Context, proposalID uint64) []types.Vote {
results := []types.Vote{}
k.IterateVotes(ctx, func(vote types.Vote) bool {
if vote.ProposalID == proposalID {
results = append(results, vote)
}
return false
})
return results
}

View File

@ -99,11 +99,7 @@ func (k Keeper) GetProposalResult(ctx sdk.Context, proposalID uint64) (bool, sdk
// TallyVotes counts all the votes on a proposal
func (k Keeper) TallyVotes(ctx sdk.Context, proposalID uint64) int64 {
var votes []types.Vote
k.IterateVotes(ctx, proposalID, func(vote types.Vote) bool {
votes = append(votes, vote)
return false
})
votes := k.GetVotesByProposal(ctx, proposalID)
return int64(len(votes))
}
@ -180,18 +176,3 @@ func (k Keeper) ValidatePubProposal(ctx sdk.Context, pubProposal types.PubPropos
}
return nil
}
// DeleteProposalAndVotes removes a proposal and its associated votes.
// TODO move to keeper.go
func (k Keeper) DeleteProposalAndVotes(ctx sdk.Context, proposalID uint64) {
var votes []types.Vote
k.IterateVotes(ctx, proposalID, func(vote types.Vote) bool {
votes = append(votes, vote)
return false
})
k.DeleteProposal(ctx, proposalID)
for _, v := range votes {
k.DeleteVote(ctx, v.ProposalID, v.Voter)
}
}

View File

@ -42,11 +42,7 @@ func NewQuerier(keeper Keeper) sdk.Querier {
func queryCommittees(ctx sdk.Context, path []string, _ abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) {
committees := []types.Committee{}
keeper.IterateCommittees(ctx, func(com types.Committee) bool {
committees = append(committees, com)
return false
})
committees := keeper.GetCommittees(ctx)
bz, err := codec.MarshalJSONIndent(keeper.cdc, committees)
if err != nil {
@ -85,13 +81,7 @@ func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keepe
return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error()))
}
proposals := []types.Proposal{}
keeper.IterateProposals(ctx, func(p types.Proposal) bool {
if p.CommitteeID == params.CommitteeID {
proposals = append(proposals, p)
}
return false
})
proposals := keeper.GetProposalsByCommittee(ctx, params.CommitteeID)
bz, err := codec.MarshalJSONIndent(keeper.cdc, proposals)
if err != nil {
@ -131,11 +121,7 @@ func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke
return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error()))
}
votes := []types.Vote{}
keeper.IterateVotes(ctx, params.ProposalID, func(v types.Vote) bool {
votes = append(votes, v)
return false
})
votes := keeper.GetVotesByProposal(ctx, params.ProposalID)
bz, err := codec.MarshalJSONIndent(keeper.cdc, votes)
if err != nil {

View File

@ -28,16 +28,12 @@ func handleCommitteeChangeProposal(ctx sdk.Context, k Keeper, committeeProposal
}
// Remove all committee's ongoing proposals
var proposals []Proposal
k.IterateProposals(ctx, func(p Proposal) bool {
if p.CommitteeID == committeeProposal.NewCommittee.ID {
proposals = append(proposals, p)
k.DeleteProposalAndVotes(ctx, p.ID)
}
return false
})
for _, p := range proposals { // split loops to avoid updating the db while iterating
k.DeleteProposalAndVotes(ctx, p.ID)
}
// update/create the committee
k.SetCommittee(ctx, committeeProposal.NewCommittee)
@ -50,16 +46,12 @@ func handleCommitteeDeleteProposal(ctx sdk.Context, k Keeper, committeeProposal
}
// Remove all committee's ongoing proposals
var proposals []Proposal
k.IterateProposals(ctx, func(p Proposal) bool {
if p.CommitteeID == committeeProposal.CommitteeID {
proposals = append(proposals, p)
k.DeleteProposalAndVotes(ctx, p.ID)
}
return false
})
for _, p := range proposals { // split loops to avoid updating the db while iterating
k.DeleteProposalAndVotes(ctx, p.ID)
}
k.DeleteCommittee(ctx, committeeProposal.CommitteeID)
return nil

View File

@ -133,19 +133,7 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_ChangeCommittee() {
suite.ctx = suite.app.NewContext(true, abci.Header{Height: 1, Time: testTime})
handler := committee.NewProposalHandler(suite.keeper)
// get proposals and votes for target committee
var proposals []committee.Proposal
var votes []committee.Vote
suite.keeper.IterateProposals(suite.ctx, func(p committee.Proposal) bool {
if p.CommitteeID == tc.proposal.NewCommittee.ID {
proposals = append(proposals, p)
suite.keeper.IterateVotes(suite.ctx, p.ID, func(v committee.Vote) bool {
votes = append(votes, v)
return false
})
}
return false
})
oldProposals := suite.keeper.GetProposalsByCommittee(suite.ctx, tc.proposal.NewCommittee.ID)
// Run
err := handler(suite.ctx, tc.proposal)
@ -153,19 +141,15 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_ChangeCommittee() {
// Check
if tc.expectPass {
suite.NoError(err)
// check proposal is accurate
// check committee is accurate
actualCom, found := suite.keeper.GetCommittee(suite.ctx, tc.proposal.NewCommittee.ID)
suite.True(found)
suite.Equal(tc.proposal.NewCommittee, actualCom)
// check proposals and votes for this committee have been removed
for _, p := range proposals {
_, found := suite.keeper.GetProposal(suite.ctx, p.ID)
suite.False(found)
}
for _, v := range votes {
_, found := suite.keeper.GetVote(suite.ctx, v.ProposalID, v.Voter)
suite.False(found)
suite.Empty(suite.keeper.GetProposalsByCommittee(suite.ctx, tc.proposal.NewCommittee.ID))
for _, p := range oldProposals {
suite.Empty(suite.keeper.GetVotesByProposal(suite.ctx, p.ID))
}
} else {
suite.Error(err)
@ -211,19 +195,7 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_DeleteCommittee() {
suite.ctx = suite.app.NewContext(true, abci.Header{Height: 1, Time: testTime})
handler := committee.NewProposalHandler(suite.keeper)
// get proposals and votes for target committee
var proposals []committee.Proposal
var votes []committee.Vote
suite.keeper.IterateProposals(suite.ctx, func(p committee.Proposal) bool {
if p.CommitteeID == tc.proposal.CommitteeID {
proposals = append(proposals, p)
suite.keeper.IterateVotes(suite.ctx, p.ID, func(v committee.Vote) bool {
votes = append(votes, v)
return false
})
}
return false
})
oldProposals := suite.keeper.GetProposalsByCommittee(suite.ctx, tc.proposal.CommitteeID)
// Run
err := handler(suite.ctx, tc.proposal)
@ -231,18 +203,14 @@ func (suite *ProposalHandlerTestSuite) TestProposalHandler_DeleteCommittee() {
// Check
if tc.expectPass {
suite.NoError(err)
// check proposal is accurate
// check committee has been removed
_, found := suite.keeper.GetCommittee(suite.ctx, tc.proposal.CommitteeID)
suite.False(found)
// check proposals and votes for this committee have been removed
for _, p := range proposals {
_, found := suite.keeper.GetProposal(suite.ctx, p.ID)
suite.False(found)
}
for _, v := range votes {
_, found := suite.keeper.GetVote(suite.ctx, v.ProposalID, v.Voter)
suite.False(found)
suite.Empty(suite.keeper.GetProposalsByCommittee(suite.ctx, tc.proposal.CommitteeID))
for _, p := range oldProposals {
suite.Empty(suite.keeper.GetVotesByProposal(suite.ctx, p.ID))
}
} else {
suite.Error(err)