github.com/KiraCore/sekai@v0.3.43/x/gov/keeper/poll.go (about)

     1  package keeper
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"github.com/KiraCore/sekai/x/gov/types"
     7  	sdk "github.com/cosmos/cosmos-sdk/types"
     8  	"time"
     9  )
    10  
    11  func (k Keeper) GetNextPollIDAndIncrement(ctx sdk.Context) uint64 {
    12  	pollID := k.GetNextPollID(ctx)
    13  	k.SetNextPollID(ctx, pollID+1)
    14  	return pollID
    15  }
    16  
    17  func (k Keeper) GetNextPollID(ctx sdk.Context) uint64 {
    18  	store := ctx.KVStore(k.storeKey)
    19  
    20  	bz := store.Get(NextPollIDPrefix)
    21  	if bz == nil {
    22  		return 1
    23  	}
    24  
    25  	pollID := sdk.BigEndianToUint64(bz)
    26  	return pollID
    27  }
    28  
    29  func (k Keeper) SetNextPollID(ctx sdk.Context, pollID uint64) {
    30  	store := ctx.KVStore(k.storeKey)
    31  	store.Set(NextPollIDPrefix, sdk.Uint64ToBigEndian(pollID))
    32  }
    33  
    34  func (k Keeper) PollCreate(ctx sdk.Context, msg *types.MsgPollCreate) (uint64, error) {
    35  	var roles []uint64
    36  	pollID := k.GetNextPollIDAndIncrement(ctx)
    37  	options := new(types.PollOptions)
    38  
    39  	options.Type = msg.ValueType
    40  	options.Count = msg.ValueCount
    41  	options.Choices = msg.PossibleChoices
    42  
    43  	duration, err := time.ParseDuration(msg.Duration)
    44  	if err != nil {
    45  		return pollID, fmt.Errorf("invalid duration: %w", err)
    46  	}
    47  
    48  	for _, v := range msg.PollValues {
    49  		options.Values = append(options.Values, v)
    50  	}
    51  
    52  	for _, sid := range msg.Roles {
    53  		role, _ := k.GetRoleBySid(ctx, sid)
    54  		roles = append(roles, uint64(role.Id))
    55  	}
    56  
    57  	poll, err := types.NewPoll(
    58  		pollID,
    59  		msg.Creator,
    60  		msg.Title,
    61  		msg.Description,
    62  		msg.Reference,
    63  		msg.Checksum,
    64  		roles,
    65  		options,
    66  		time.Now().Add(duration),
    67  	)
    68  
    69  	if err != nil {
    70  		return pollID, err
    71  	}
    72  
    73  	k.SavePoll(ctx, poll)
    74  	k.AddAddressPoll(ctx, poll)
    75  	k.AddToActivePolls(ctx, poll)
    76  
    77  	return pollID, nil
    78  }
    79  
    80  func (k Keeper) SavePoll(ctx sdk.Context, poll types.Poll) {
    81  	store := ctx.KVStore(k.storeKey)
    82  	key := append(PollPrefix, sdk.Uint64ToBigEndian(poll.PollId)...)
    83  	store.Set(key, k.cdc.MustMarshal(&poll))
    84  }
    85  
    86  func (k Keeper) AddAddressPoll(ctx sdk.Context, poll types.Poll) {
    87  	store := ctx.KVStore(k.storeKey)
    88  	addressKey := append(PollPrefix, poll.Creator.Bytes()...)
    89  	key := append(addressKey, sdk.Uint64ToBigEndian(poll.PollId)...)
    90  	store.Set(key, sdk.Uint64ToBigEndian(poll.PollId))
    91  }
    92  
    93  func (k Keeper) AddToActivePolls(ctx sdk.Context, poll types.Poll) {
    94  	store := ctx.KVStore(k.storeKey)
    95  	key := append(PollsByTimeKey(poll.VotingEndTime), sdk.Uint64ToBigEndian(poll.PollId)...)
    96  	store.Set(key, sdk.Uint64ToBigEndian(poll.PollId))
    97  }
    98  
    99  func (k Keeper) RemoveActivePoll(ctx sdk.Context, poll types.Poll) {
   100  	store := ctx.KVStore(k.storeKey)
   101  	key := append(PollsByTimeKey(poll.VotingEndTime), sdk.Uint64ToBigEndian(poll.PollId)...)
   102  	store.Delete(key)
   103  }
   104  
   105  func (k Keeper) PollVote(ctx sdk.Context, msg *types.MsgPollVote) error {
   106  	vote := types.PollVote{
   107  		Voter:       msg.Voter,
   108  		PollId:      msg.PollId,
   109  		Option:      msg.Option,
   110  		CustomValue: msg.Value,
   111  	}
   112  
   113  	store := ctx.KVStore(k.storeKey)
   114  	bz := k.cdc.MustMarshal(&vote)
   115  	store.Set(PollVoteKey(vote.PollId, vote.Voter), bz)
   116  
   117  	return nil
   118  }
   119  
   120  func (k Keeper) GetPoll(ctx sdk.Context, pollID uint64) (types.Poll, error) {
   121  	store := ctx.KVStore(k.storeKey)
   122  	bz := store.Get(append(PollPrefix, sdk.Uint64ToBigEndian(pollID)...))
   123  
   124  	if bz == nil {
   125  		return types.Poll{}, types.ErrPollsNotFount
   126  	}
   127  
   128  	var poll types.Poll
   129  	k.cdc.MustUnmarshal(bz, &poll)
   130  
   131  	return poll, nil
   132  }
   133  
   134  func (k Keeper) GetPollsIdsByAddress(ctx sdk.Context, address sdk.AccAddress) []uint64 {
   135  	var ids []uint64
   136  	store := ctx.KVStore(k.storeKey)
   137  	addressKey := append(PollPrefix, address.Bytes()...)
   138  	iterator := sdk.KVStorePrefixIterator(store, addressKey)
   139  	defer iterator.Close()
   140  
   141  	for ; iterator.Valid(); iterator.Next() {
   142  		id := binary.BigEndian.Uint64(iterator.Value())
   143  		ids = append(ids, id)
   144  	}
   145  
   146  	return ids
   147  }
   148  
   149  func (k Keeper) GetPollsByAddress(ctx sdk.Context, address sdk.AccAddress) ([]types.Poll, error) {
   150  	ids := k.GetPollsIdsByAddress(ctx, address)
   151  	var polls []types.Poll
   152  
   153  	for _, v := range ids {
   154  		poll, err := k.GetPoll(ctx, v)
   155  		if err != nil {
   156  			return nil, err
   157  		}
   158  		polls = append(polls, poll)
   159  	}
   160  
   161  	return polls, nil
   162  }
   163  
   164  func (k Keeper) GetPollVotes(ctx sdk.Context, pollID uint64) types.PollVotes {
   165  	var votes types.PollVotes
   166  
   167  	iterator := k.GetPollVotesIterator(ctx, pollID)
   168  	defer iterator.Close()
   169  	for ; iterator.Valid(); iterator.Next() {
   170  		var vote types.PollVote
   171  		k.cdc.MustUnmarshal(iterator.Value(), &vote)
   172  		votes = append(votes, vote)
   173  	}
   174  
   175  	return votes
   176  }
   177  
   178  func (k Keeper) GetPollVotesIterator(ctx sdk.Context, pollID uint64) sdk.Iterator {
   179  	store := ctx.KVStore(k.storeKey)
   180  	return sdk.KVStorePrefixIterator(store, PollVotesKey(pollID))
   181  }
   182  
   183  func (k Keeper) GetPollsWithFinishedVotingEndTimeIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
   184  	store := ctx.KVStore(k.storeKey)
   185  	return store.Iterator(ActivePollPrefix, sdk.PrefixEndBytes(PollsByTimeKey(endTime)))
   186  }
   187  
   188  func PollsByTimeKey(endTime time.Time) []byte {
   189  	return append(ActivePollPrefix, sdk.FormatTimeBytes(endTime)...)
   190  }
   191  
   192  func PollVotesKey(pollId uint64) []byte {
   193  	return append(PollVotesPrefix, sdk.Uint64ToBigEndian(pollId)...)
   194  }
   195  
   196  func PollVoteKey(pollId uint64, address sdk.AccAddress) []byte {
   197  	return append(PollVotesKey(pollId), address.Bytes()...)
   198  }