Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[x/act V2]: Add MsgVote handling #794

Merged
merged 11 commits into from
Sep 10, 2024
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{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Pitasi why do we need this here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's a type check.


// 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{}
artur-abliazimov marked this conversation as resolved.
Show resolved Hide resolved

// 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{}
artur-abliazimov marked this conversation as resolved.
Show resolved Hide resolved

// TryExecuteVotedAction checks if the action's intent is satisfied and stores the
artur-abliazimov marked this conversation as resolved.
Show resolved Hide resolved
// result in the database.
func (k Keeper) TryExecuteVotedAction(ctx context.Context, act *types.Action) error {
artur-abliazimov marked this conversation as resolved.
Show resolved Hide resolved
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 {
artur-abliazimov marked this conversation as resolved.
Show resolved Hide resolved
return err
}
if err := k.ActionKeeper.Set(ctx, *act); err != nil {
return err
}
}

return nil
}
artur-abliazimov marked this conversation as resolved.
Show resolved Hide resolved

// 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 {
Pitasi marked this conversation as resolved.
Show resolved Hide resolved
return nil, err
}

if err := k.TryExecuteVotedAction(ctx, &act); err != nil {
return nil, err
}
artur-abliazimov marked this conversation as resolved.
Show resolved Hide resolved

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,
artur-abliazimov marked this conversation as resolved.
Show resolved Hide resolved
}
}

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
}
artur-abliazimov marked this conversation as resolved.
Show resolved Hide resolved
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")
artur-abliazimov marked this conversation as resolved.
Show resolved Hide resolved
)
Loading