2020-03-10 21:41:10 +00:00
package keeper
2020-03-04 19:16:27 +00:00
import (
2020-03-10 22:29:16 +00:00
"github.com/cosmos/cosmos-sdk/codec"
2020-03-10 23:16:22 +00:00
"github.com/cosmos/cosmos-sdk/store/prefix"
2020-03-04 19:16:27 +00:00
sdk "github.com/cosmos/cosmos-sdk/types"
2020-03-10 22:29:16 +00:00
2020-03-11 19:27:36 +00:00
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
2020-03-04 19:16:27 +00:00
"github.com/kava-labs/kava/x/committee/types"
)
type Keeper struct {
2020-03-10 22:29:16 +00:00
cdc * codec . Codec
storeKey sdk . StoreKey
2020-03-11 19:27:36 +00:00
// Proposal router
router govtypes . Router
2020-03-10 22:29:16 +00:00
}
2020-03-04 19:16:27 +00:00
2020-03-11 19:27:36 +00:00
func NewKeeper ( cdc * codec . Codec , storeKey sdk . StoreKey , router govtypes . Router ) Keeper {
// It is vital to seal the governance proposal router here as to not allow
// further handlers to be registered after the keeper is created since this
// could create invalid or non-deterministic behavior.
// TODO why?
// Not sealing the router because for some reason the function panics if it has already been sealed and there is no way to tell if has already been called.
// router.Seal()
2020-03-10 22:29:16 +00:00
return Keeper {
cdc : cdc ,
storeKey : storeKey ,
2020-03-11 19:27:36 +00:00
router : router ,
2020-03-10 22:29:16 +00:00
}
2020-03-04 19:16:27 +00:00
}
2020-03-11 19:52:25 +00:00
// ---------- Committees ----------
2020-03-10 21:41:10 +00:00
2020-03-10 23:28:25 +00:00
// GetCommittee gets a committee from the store.
2020-03-10 21:41:10 +00:00
func ( k Keeper ) GetCommittee ( ctx sdk . Context , committeeID uint64 ) ( types . Committee , bool ) {
2020-03-10 23:16:22 +00:00
store := prefix . NewStore ( ctx . KVStore ( k . storeKey ) , types . CommitteeKeyPrefix )
bz := store . Get ( types . GetKeyFromID ( committeeID ) )
if bz == nil {
return types . Committee { } , false
}
var committee types . Committee
k . cdc . MustUnmarshalBinaryLengthPrefixed ( bz , & committee )
return committee , true
2020-03-10 21:41:10 +00:00
}
2020-03-10 23:28:25 +00:00
// SetCommittee puts a committee into the store.
2020-03-10 23:16:22 +00:00
func ( k Keeper ) SetCommittee ( ctx sdk . Context , committee types . Committee ) {
store := prefix . NewStore ( ctx . KVStore ( k . storeKey ) , types . CommitteeKeyPrefix )
bz := k . cdc . MustMarshalBinaryLengthPrefixed ( committee )
store . Set ( types . GetKeyFromID ( committee . ID ) , bz )
2020-03-10 21:41:10 +00:00
}
2020-03-10 23:28:25 +00:00
// DeleteCommittee removes a committee from the store.
func ( k Keeper ) DeleteCommittee ( ctx sdk . Context , committeeID uint64 ) {
store := prefix . NewStore ( ctx . KVStore ( k . storeKey ) , types . CommitteeKeyPrefix )
store . Delete ( types . GetKeyFromID ( committeeID ) )
}
2020-03-11 19:52:25 +00:00
// ---------- Proposals ----------
2020-03-11 00:58:42 +00:00
// SetNextProposalID stores an ID to be used for the next created proposal
func ( k Keeper ) SetNextProposalID ( ctx sdk . Context , id uint64 ) {
store := ctx . KVStore ( k . storeKey )
store . Set ( types . NextProposalIDKey , types . GetKeyFromID ( id ) )
}
// GetNextProposalID reads the next available global ID from store
func ( k Keeper ) GetNextProposalID ( ctx sdk . Context ) ( uint64 , sdk . Error ) {
store := ctx . KVStore ( k . storeKey )
bz := store . Get ( types . NextProposalIDKey )
if bz == nil {
return 0 , sdk . ErrInternal ( "proposal ID not set at genesis" )
}
return types . Uint64FromBytes ( bz ) , nil
}
// IncrementNextProposalID increments the next proposal ID in the store by 1.
func ( k Keeper ) IncrementNextProposalID ( ctx sdk . Context ) sdk . Error {
id , err := k . GetNextProposalID ( ctx )
if err != nil {
return err
}
k . SetNextProposalID ( ctx , id + 1 )
return nil
}
// StoreNewProposal stores a proposal, adding a new ID
2020-03-11 19:27:36 +00:00
func ( k Keeper ) StoreNewProposal ( ctx sdk . Context , committeeID uint64 , pubProposal types . PubProposal ) ( uint64 , sdk . Error ) {
2020-03-11 00:58:42 +00:00
newProposalID , err := k . GetNextProposalID ( ctx )
if err != nil {
return 0 , err
}
2020-03-11 19:27:36 +00:00
proposal := types . Proposal {
PubProposal : pubProposal ,
ID : newProposalID ,
CommitteeID : committeeID ,
}
2020-03-11 00:58:42 +00:00
k . SetProposal ( ctx , proposal )
err = k . IncrementNextProposalID ( ctx )
if err != nil {
return 0 , err
}
return newProposalID , nil
}
2020-03-10 23:28:25 +00:00
// GetProposal gets a proposal from the store.
2020-03-10 23:16:22 +00:00
func ( k Keeper ) GetProposal ( ctx sdk . Context , proposalID uint64 ) ( types . Proposal , bool ) {
store := prefix . NewStore ( ctx . KVStore ( k . storeKey ) , types . ProposalKeyPrefix )
bz := store . Get ( types . GetKeyFromID ( proposalID ) )
if bz == nil {
return types . Proposal { } , false
}
var proposal types . Proposal
k . cdc . MustUnmarshalBinaryLengthPrefixed ( bz , & proposal )
return proposal , true
2020-03-10 21:41:10 +00:00
}
2020-03-10 23:28:25 +00:00
// SetProposal puts a proposal into the store.
2020-03-10 23:16:22 +00:00
func ( k Keeper ) SetProposal ( ctx sdk . Context , proposal types . Proposal ) {
store := prefix . NewStore ( ctx . KVStore ( k . storeKey ) , types . ProposalKeyPrefix )
bz := k . cdc . MustMarshalBinaryLengthPrefixed ( proposal )
store . Set ( types . GetKeyFromID ( proposal . ID ) , bz )
2020-03-10 21:41:10 +00:00
}
2020-03-10 23:28:25 +00:00
// DeleteProposal removes a proposal from the store.
func ( k Keeper ) DeleteProposal ( ctx sdk . Context , proposalID uint64 ) {
store := prefix . NewStore ( ctx . KVStore ( k . storeKey ) , types . ProposalKeyPrefix )
store . Delete ( types . GetKeyFromID ( proposalID ) )
}
2020-03-11 19:52:25 +00:00
// ---------- Votes ----------
2020-03-11 19:27:36 +00:00
2020-03-10 23:28:25 +00:00
// GetVote gets a vote from the store.
2020-03-10 23:16:22 +00:00
func ( k Keeper ) GetVote ( ctx sdk . Context , proposalID uint64 , voter sdk . AccAddress ) ( types . Vote , bool ) {
store := prefix . NewStore ( ctx . KVStore ( k . storeKey ) , types . VoteKeyPrefix )
bz := store . Get ( types . GetVoteKey ( proposalID , voter ) )
if bz == nil {
return types . Vote { } , false
}
var vote types . Vote
k . cdc . MustUnmarshalBinaryLengthPrefixed ( bz , & vote )
return vote , true
2020-03-10 21:41:10 +00:00
}
2020-03-10 23:28:25 +00:00
// SetVote puts a vote into the store.
2020-03-10 23:16:22 +00:00
func ( k Keeper ) SetVote ( ctx sdk . Context , vote types . Vote ) {
store := prefix . NewStore ( ctx . KVStore ( k . storeKey ) , types . VoteKeyPrefix )
bz := k . cdc . MustMarshalBinaryLengthPrefixed ( vote )
store . Set ( types . GetVoteKey ( vote . ProposalID , vote . Voter ) , bz )
2020-03-10 21:41:10 +00:00
}
2020-03-10 23:28:25 +00:00
// DeleteVote removes a Vote from the store.
func ( k Keeper ) DeleteVote ( ctx sdk . Context , proposalID uint64 , voter sdk . AccAddress ) {
store := prefix . NewStore ( ctx . KVStore ( k . storeKey ) , types . VoteKeyPrefix )
store . Delete ( types . GetVoteKey ( proposalID , voter ) )
}
2020-03-11 19:52:25 +00:00
// IterateVotes provides an iterator over all stored votes for a given proposal.
// 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 ) ... ) )
defer iterator . Close ( )
for ; iterator . Valid ( ) ; iterator . Next ( ) {
var vote types . Vote
k . cdc . MustUnmarshalBinaryLengthPrefixed ( iterator . Value ( ) , & vote )
if cb ( vote ) {
break
}
}
}