github.com/cosmos/cosmos-sdk@v0.50.10/x/group/keeper/tally.go (about) 1 package keeper 2 3 import ( 4 errorsmod "cosmossdk.io/errors" 5 6 sdk "github.com/cosmos/cosmos-sdk/types" 7 sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" 8 "github.com/cosmos/cosmos-sdk/x/group" 9 "github.com/cosmos/cosmos-sdk/x/group/errors" 10 "github.com/cosmos/cosmos-sdk/x/group/internal/orm" 11 ) 12 13 // Tally is a function that tallies a proposal by iterating through its votes, 14 // and returns the tally result without modifying the proposal or any state. 15 func (k Keeper) Tally(ctx sdk.Context, p group.Proposal, groupID uint64) (group.TallyResult, error) { 16 // If proposal has already been tallied and updated, then its status is 17 // accepted/rejected, in which case we just return the previously stored result. 18 // 19 // In all other cases (including withdrawn, aborted...) we do the tally 20 // again. 21 if p.Status == group.PROPOSAL_STATUS_ACCEPTED || p.Status == group.PROPOSAL_STATUS_REJECTED { 22 return p.FinalTallyResult, nil 23 } 24 25 it, err := k.voteByProposalIndex.Get(ctx.KVStore(k.key), p.Id) 26 if err != nil { 27 return group.TallyResult{}, err 28 } 29 defer it.Close() 30 31 tallyResult := group.DefaultTallyResult() 32 33 for { 34 var vote group.Vote 35 _, err = it.LoadNext(&vote) 36 if errors.ErrORMIteratorDone.Is(err) { 37 break 38 } 39 if err != nil { 40 return group.TallyResult{}, err 41 } 42 43 var member group.GroupMember 44 err := k.groupMemberTable.GetOne(ctx.KVStore(k.key), orm.PrimaryKey(&group.GroupMember{ 45 GroupId: groupID, 46 Member: &group.Member{Address: vote.Voter}, 47 }), &member) 48 49 switch { 50 case sdkerrors.ErrNotFound.Is(err): 51 // If the member left the group after voting, then we simply skip the 52 // vote. 53 continue 54 case err != nil: 55 // For any other errors, we stop and return the error. 56 return group.TallyResult{}, err 57 } 58 59 if err := tallyResult.Add(vote, member.Member.Weight); err != nil { 60 return group.TallyResult{}, errorsmod.Wrap(err, "add new vote") 61 } 62 } 63 64 return tallyResult, nil 65 }