Skip to content

Commit

Permalink
Add MsgVote handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Artur Abliazimov committed Sep 5, 2024
1 parent f2f1771 commit 2a83ffd
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 1 deletion.
67 changes: 67 additions & 0 deletions warden/x/act/keeper/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,73 @@ func (approvers ApproversEnv) Get(name string) (object.Object, bool) {

var _ shield.Environment = ApproversEnv{}

// ActionApprovedVotesEnv is an environment that resolves action positive votes addresses to true.
type ActionApprovedVotesEnv []*types.ActionVote

// Get implements positive action vote evaluator.Environment.
func (votes ActionApprovedVotesEnv) Get(name string) (object.Object, bool) {
for _, s := range votes {
if s.Participant == name && s.Vote == types.ActionVoteType_VOTE_TYPE_APPROVED {
return object.TRUE, true
}
}
return object.FALSE, true
}

var _ shield.Environment = ActionApprovedVotesEnv{}

// ActionRejectedVotesEnv is an environment that resolves action negative votes addresses to true.
type ActionRejectedVotesEnv []*types.ActionVote

// Get implements negative action vote evaluator.Environment.
func (votes ActionRejectedVotesEnv) Get(name string) (object.Object, bool) {
for _, s := range votes {
if s.Participant == name && s.Vote == types.ActionVoteType_VOTE_TYPE_REJECTED {
return object.TRUE, true
}
}
return object.FALSE, true
}

var _ shield.Environment = ActionRejectedVotesEnv{}

// TryExecuteVotedAction checks if the action's intent is satisfied and stores the
// result in the database.
func (k Keeper) TryExecuteVotedAction(ctx context.Context, act *types.Action) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)

approved, err := act.Rule.Eval(ctx, ActionApprovedVotesEnv(act.Votes))

if err != nil {
return err
}

if approved {
if err := k.executeAction(ctx, act); err != nil {
return err
}

return nil
}

rejected, err := act.Rule.Eval(ctx, ActionRejectedVotesEnv(act.Votes))

if err != nil {
return err
}

if rejected {
if err := act.SetStatus(sdkCtx, types.ActionStatus_ACTION_STATUS_REVOKED); err != nil {
return err
}
if err := k.ActionKeeper.Set(ctx, *act); err != nil {
return err
}
}

return nil
}

// TryExecuteAction checks if the action's intent is satisfied and stores the
// result in the database.
func (k Keeper) TryExecuteAction(ctx context.Context, act *types.Action) error {
Expand Down
35 changes: 34 additions & 1 deletion warden/x/act/keeper/msg_server_vote_for_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,43 @@ package keeper

import (
"context"
sdk "github.com/cosmos/cosmos-sdk/types"

types "github.com/warden-protocol/wardenprotocol/warden/x/act/types/v1beta1"
)

func (k msgServer) VoteForAction(goCtx context.Context, msg *types.MsgVoteForAction) (*types.MsgVoteForActionResponse, error) {
panic("VoteForAction not implemented")
ctx := sdk.UnwrapSDKContext(goCtx)
act, err := k.ActionKeeper.Get(ctx, msg.ActionId)

if err != nil {
return nil, err
}

if act.TimeoutHeight > 0 && act.TimeoutHeight < uint64(ctx.BlockHeight()) {
if err := act.SetStatus(ctx, types.ActionStatus_ACTION_STATUS_TIMEOUT); err != nil {
return nil, err
}
if err := k.ActionKeeper.Set(ctx, act); err != nil {
return nil, err
}

return &types.MsgVoteForActionResponse{
Status: act.Status.String(),
}, nil
}

if err := act.AddVote(ctx, msg.Participant, msg.Vote); err != nil {
return nil, err
}

if err := k.ActionKeeper.Set(ctx, act); err != nil {
return nil, err
}

if err := k.TryExecuteVotedAction(ctx, &act); err != nil {
return nil, err
}

return &types.MsgVoteForActionResponse{Status: act.Status.String()}, nil
}
33 changes: 33 additions & 0 deletions warden/x/act/types/v1beta1/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ func NewApprover(address string, timestamp time.Time) *Approver {
}
}

func NewVote(participant string, vote ActionVoteType, timestamp time.Time) *ActionVote {
return &ActionVote{
Participant: participant,
VotedAt: timestamp,
Vote: vote,
}
}

func (a *Action) SetId(id uint64) { a.Id = id }

func (a *Action) SetResult(ctx sdk.Context, result *codectypes.Any) error {
Expand Down Expand Up @@ -63,3 +71,28 @@ func (a *Action) AddApprover(ctx sdk.Context, address string) error {

return nil
}

func (a *Action) AddVote(ctx sdk.Context, participant string, vote ActionVoteType) error {
if a.Status != ActionStatus_ACTION_STATUS_PENDING {
return errors.Wrapf(ErrInvalidActionStatus, "can't add a vote to an action that's not pending")
}

for _, v := range a.Votes {
if v.Participant == participant {
return ErrActionVoteAlreadyExists
}
}

a.UpdatedAt = ctx.BlockTime()
a.Votes = append(a.Votes, NewVote(participant, vote, a.UpdatedAt))

if err := ctx.EventManager().EmitTypedEvent(&EventActionVoted{
Id: a.Id,
Participant: participant,
Vote: vote,
}); err != nil {
return err
}

return nil
}
1 change: 1 addition & 0 deletions warden/x/act/types/v1beta1/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ var (
ErrInvalidRuleDefinition = sdkerrors.Register(ModuleName, 1112, "invalid rule definition")
ErrInvalidRevoker = sdkerrors.Register(ModuleName, 1113, "this account can't revoke this action")
ErrInvalidUpdateRuleAccount = sdkerrors.Register(ModuleName, 1114, "this account can't update this rule")
ErrActionVoteAlreadyExists = sdkerrors.Register(ModuleName, 1115, "vote already exists")
)

0 comments on commit 2a83ffd

Please sign in to comment.