Skip to content

Commit

Permalink
feat: addVote
Browse files Browse the repository at this point in the history
  • Loading branch information
tkxkd0159 committed May 2, 2024
1 parent 754496b commit e30a99d
Show file tree
Hide file tree
Showing 8 changed files with 414 additions and 36 deletions.
18 changes: 18 additions & 0 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@
- [VoteOption](#lbm.fbridge.v1.VoteOption)

- [lbm/fbridge/v1/event.proto](#lbm/fbridge/v1/event.proto)
- [EventAddVoteForRole](#lbm.fbridge.v1.EventAddVoteForRole)
- [EventClaim](#lbm.fbridge.v1.EventClaim)
- [EventConfirmProvision](#lbm.fbridge.v1.EventConfirmProvision)
- [EventProvision](#lbm.fbridge.v1.EventProvision)
Expand Down Expand Up @@ -11560,6 +11561,23 @@ VoteOption enumerates the valid vote options for a given role proposal.



<a name="lbm.fbridge.v1.EventAddVoteForRole"></a>

### EventAddVoteForRole



| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `voter` | [string](#string) | | the voter address |
| `proposal_id` | [uint64](#uint64) | | the role proposal id |
| `option` | [VoteOption](#lbm.fbridge.v1.VoteOption) | | the vote option |






<a name="lbm.fbridge.v1.EventClaim"></a>

### EventClaim
Expand Down
9 changes: 9 additions & 0 deletions proto/lbm/fbridge/v1/event.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ message EventSuggestRole {
RoleProposal proposal = 1 [(gogoproto.nullable) = false];
}

message EventAddVoteForRole {
// the voter address
string voter = 1;
// the role proposal id
uint64 proposal_id = 2;
// the vote option
VoteOption option = 3;
}

message EventProvision {
// the sequence number of the bridge request
uint64 seq = 1;
Expand Down
47 changes: 45 additions & 2 deletions x/fbridge/keeper/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,25 @@ func (k Keeper) RegisterRoleProposal(ctx sdk.Context, proposer, target sdk.AccAd
return proposal, nil
}

func (k Keeper) addVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddress, option types.VoteOption) error {
proposal, found := k.GetRoleProposal(ctx, proposalID)
if !found {
return types.ErrUnknownProposal.Wrapf("#%d not found", proposalID)
}

if ctx.BlockTime().After(proposal.ExpiredAt) {
return types.ErrInactiveProposal.Wrapf("#%d already expired", proposalID)
}

if err := k.IsValidVoteOption(option); err != nil {
return err
}

k.setVote(ctx, proposalID, voter, option)

return nil
}

func (k Keeper) IsValidRole(role types.Role) error {
switch role {
case types.RoleGuardian, types.RoleOperator, types.RoleJudge:
Expand All @@ -45,6 +64,15 @@ func (k Keeper) IsValidRole(role types.Role) error {
return errors.New("unsupported role")
}

func (k Keeper) IsValidVoteOption(option types.VoteOption) error {
switch option {
case types.OptionYes, types.OptionNo:
return nil
}

return errors.New("unsupported vote option")
}

func (k Keeper) setNextProposalID(ctx sdk.Context, seq uint64) {
store := ctx.KVStore(k.storeKey)
bz := make([]byte, 8)
Expand Down Expand Up @@ -112,17 +140,32 @@ func (k Keeper) GetProposals(ctx sdk.Context) (proposals []types.RoleProposal) {
return
}

func (k Keeper) setRole(ctx sdk.Context, role types.Role, addr sdk.AccAddress) {
func (k Keeper) setVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddress, option types.VoteOption) {
store := ctx.KVStore(k.storeKey)
bz := make([]byte, 4)
binary.BigEndian.PutUint32(bz, uint32(option))
store.Set(types.VoterVoteKey(proposalID, voter), bz)
}

func (k Keeper) GetVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddress) (types.VoteOption, error) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.VoterVoteKey(proposalID, voter))
if bz == nil {
return types.OptionEmpty, types.ErrUnknownVote
}

return types.VoteOption(binary.BigEndian.Uint32(bz)), nil
}

func (k Keeper) setRole(ctx sdk.Context, role types.Role, addr sdk.AccAddress) {

Check failure on line 160 in x/fbridge/keeper/auth.go

View workflow job for this annotation

GitHub Actions / golangci-lint

func `Keeper.setRole` is unused (unused)
store := ctx.KVStore(k.storeKey)
bz := make([]byte, 4)
binary.BigEndian.PutUint32(bz, uint32(role))
store.Set(types.RoleKey(addr), bz)
}

func (k Keeper) GetRole(ctx sdk.Context, addr sdk.AccAddress) types.Role {
store := ctx.KVStore(k.storeKey)

bz := store.Get(types.RoleKey(addr))
if bz == nil {
return types.RoleEmpty
Expand Down
28 changes: 28 additions & 0 deletions x/fbridge/keeper/genesis.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper

import (
"encoding/binary"

Check failure on line 4 in x/fbridge/keeper/genesis.go

View workflow job for this annotation

GitHub Actions / golangci-lint

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/Finschia/finschia-sdk) --custom-order (gci)
sdk "github.com/Finschia/finschia-sdk/types"
"github.com/Finschia/finschia-sdk/x/fbridge/types"
)
Expand Down Expand Up @@ -28,5 +29,32 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
NextRoleProposalId: k.GetNextProposalID(ctx),
RoleMetadata: k.GetRoleMetadata(ctx),
RoleProposals: k.GetProposals(ctx),
Votes: k.GetAllVotes(ctx),
}
}

// IterateVotes iterates over the all the votes for role proposals and performs a callback function
func (k Keeper) IterateVotes(ctx sdk.Context, cb func(proposal types.Vote) (stop bool)) {
store := ctx.KVStore(k.storeKey)

iterator := sdk.KVStorePrefixIterator(store, types.KeyProposalPrefix)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
id, voter := types.SplitVoterVoteKey(iterator.Key())
opt := types.VoteOption(binary.BigEndian.Uint32(iterator.Value()))
v := types.Vote{ProposalId: id, Voter: voter.String(), Option: opt}
k.cdc.MustUnmarshal(iterator.Value(), &v)
if cb(v) {
break
}
}
}

// GetAllVotes returns all the votes from the store
func (k Keeper) GetAllVotes(ctx sdk.Context) (votes []types.Vote) {
k.IterateVotes(ctx, func(vote types.Vote) bool {
votes = append(votes, vote)
return false
})
return
}
25 changes: 24 additions & 1 deletion x/fbridge/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,30 @@ func (m msgServer) SuggestRole(goCtx context.Context, msg *types.MsgSuggestRole)
}

func (m msgServer) AddVoteForRole(goCtx context.Context, msg *types.MsgAddVoteForRole) (*types.MsgAddVoteForRoleResponse, error) {
panic("implement me")
ctx := sdk.UnwrapSDKContext(goCtx)

voter, err := sdk.AccAddressFromBech32(msg.From)
if err != nil {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid proposer address (%s)", err)
}

if err := m.IsValidVoteOption(msg.Option); err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
}

if err := m.addVote(ctx, msg.ProposalId, voter, msg.Option); err != nil {
return nil, err
}

if err := ctx.EventManager().EmitTypedEvent(&types.EventAddVoteForRole{
Voter: msg.From,
ProposalId: msg.ProposalId,
Option: msg.Option,
}); err != nil {
panic(err)
}

return &types.MsgAddVoteForRoleResponse{}, nil
}

func (m msgServer) Halt(ctx context.Context, msg *types.MsgHalt) (*types.MsgHaltResponse, error) {
Expand Down
9 changes: 9 additions & 0 deletions x/fbridge/types/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package types

import sdkerrors "github.com/Finschia/finschia-sdk/types/errors"

var (
ErrUnknownProposal = sdkerrors.Register(ModuleName, 2, "unknown proposal")
ErrInactiveProposal = sdkerrors.Register(ModuleName, 3, "inactive proposal")
ErrUnknownVote = sdkerrors.Register(ModuleName, 4, "unknown vote")
)
Loading

0 comments on commit e30a99d

Please sign in to comment.