package keeper import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/gov/types" ) // AddVote adds a vote on a specific proposal func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress, option types.VoteOption) error { proposal, ok := keeper.GetProposal(ctx, proposalID) if !ok { return sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) } if proposal.Status != types.StatusVotingPeriod { return sdkerrors.Wrapf(types.ErrInactiveProposal, "%d", proposalID) } if !types.ValidVoteOption(option) { return sdkerrors.Wrap(types.ErrInvalidVote, option.String()) } vote := types.NewVote(proposalID, voterAddr, option) keeper.SetVote(ctx, vote) ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeProposalVote, sdk.NewAttribute(types.AttributeKeyOption, option.String()), sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposalID)), ), ) return nil } // GetAllVotes returns all the votes from the store func (keeper Keeper) GetAllVotes(ctx sdk.Context) (votes types.Votes) { keeper.IterateAllVotes(ctx, func(vote types.Vote) bool { votes = append(votes, vote) return false }) return } // GetVotes returns all the votes from a proposal func (keeper Keeper) GetVotes(ctx sdk.Context, proposalID uint64) (votes types.Votes) { keeper.IterateVotes(ctx, proposalID, func(vote types.Vote) bool { votes = append(votes, vote) return false }) return } // GetVote gets the vote from an address on a specific proposal func (keeper Keeper) GetVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) (vote types.Vote, found bool) { store := ctx.KVStore(keeper.storeKey) bz := store.Get(types.VoteKey(proposalID, voterAddr)) if bz == nil { return vote, false } keeper.cdc.MustUnmarshalBinaryBare(bz, &vote) return vote, true } // SetVote sets a Vote to the gov store func (keeper Keeper) SetVote(ctx sdk.Context, vote types.Vote) { store := ctx.KVStore(keeper.storeKey) bz := keeper.cdc.MustMarshalBinaryBare(&vote) store.Set(types.VoteKey(vote.ProposalId, vote.Voter), bz) } // IterateAllVotes iterates over the all the stored votes and performs a callback function func (keeper Keeper) IterateAllVotes(ctx sdk.Context, cb func(vote types.Vote) (stop bool)) { store := ctx.KVStore(keeper.storeKey) iterator := sdk.KVStorePrefixIterator(store, types.VotesKeyPrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { var vote types.Vote keeper.cdc.MustUnmarshalBinaryBare(iterator.Value(), &vote) if cb(vote) { break } } } // IterateVotes iterates over the all the proposals votes and performs a callback function func (keeper Keeper) IterateVotes(ctx sdk.Context, proposalID uint64, cb func(vote types.Vote) (stop bool)) { store := ctx.KVStore(keeper.storeKey) iterator := sdk.KVStorePrefixIterator(store, types.VotesKey(proposalID)) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { var vote types.Vote keeper.cdc.MustUnmarshalBinaryBare(iterator.Value(), &vote) if cb(vote) { break } } } // deleteVote deletes a vote from a given proposalID and voter from the store func (keeper Keeper) deleteVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) { store := ctx.KVStore(keeper.storeKey) store.Delete(types.VoteKey(proposalID, voterAddr)) }