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

refactor(x/gov): move ValidateBasic to msg server #15832

Merged
merged 15 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions x/gov/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import (
"strconv"

"cosmossdk.io/errors"
"cosmossdk.io/math"
"github.com/armon/go-metrics"

"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
Expand All @@ -29,6 +31,35 @@ var _ v1.MsgServer = msgServer{}

// SubmitProposal implements the MsgServer.SubmitProposal method.
func (k msgServer) SubmitProposal(goCtx context.Context, msg *v1.MsgSubmitProposal) (*v1.MsgSubmitProposalResponse, error) {
if msg.Title == "" {
return nil, errors.Wrap(sdkerrors.ErrInvalidRequest, "proposal title cannot be empty")
}
if msg.Summary == "" {
return nil, errors.Wrap(sdkerrors.ErrInvalidRequest, "proposal summary cannot be empty")
}

if _, err := sdk.AccAddressFromBech32(msg.Proposer); err != nil {
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid proposer address: %s", err)
}

deposit := sdk.NewCoins(msg.InitialDeposit...)
atheeshp marked this conversation as resolved.
Show resolved Hide resolved
if !deposit.IsValid() {
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
return nil, errors.Wrap(sdkerrors.ErrInvalidCoins, deposit.String())
}

if deposit.IsAnyNegative() {
return nil, errors.Wrap(sdkerrors.ErrInvalidCoins, deposit.String())
}

// Check that either metadata or Msgs length is non nil.
if len(msg.Messages) == 0 && len(msg.Metadata) == 0 {
return nil, errors.Wrap(govtypes.ErrNoProposalMsgs, "either metadata or Msgs length must be non-nil")
}

if err := validateMsgs(msg); err != nil {
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
return nil, err
}

ctx := sdk.UnwrapSDKContext(goCtx)

initialDeposit := msg.GetInitialDeposit()
Expand Down Expand Up @@ -85,6 +116,10 @@ func (k msgServer) SubmitProposal(goCtx context.Context, msg *v1.MsgSubmitPropos

// CancelProposals implements the MsgServer.CancelProposal method.
func (k msgServer) CancelProposal(goCtx context.Context, msg *v1.MsgCancelProposal) (*v1.MsgCancelProposalResponse, error) {
if _, err := sdk.AccAddressFromBech32(msg.Proposer); err != nil {
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid proposer address: %s", err)
}

ctx := sdk.UnwrapSDKContext(goCtx)
_, err := k.authKeeper.StringToBytes(msg.Proposer)
if err != nil {
Expand Down Expand Up @@ -139,6 +174,14 @@ func (k msgServer) ExecLegacyContent(goCtx context.Context, msg *v1.MsgExecLegac

// Vote implements the MsgServer.Vote method.
func (k msgServer) Vote(goCtx context.Context, msg *v1.MsgVote) (*v1.MsgVoteResponse, error) {
if _, err := sdk.AccAddressFromBech32(msg.Voter); err != nil {
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid voter address: %s", err)
}

if !v1.ValidVoteOption(msg.Option) {
return nil, errors.Wrap(govtypes.ErrInvalidVote, msg.Option.String())
}

ctx := sdk.UnwrapSDKContext(goCtx)
accAddr, err := k.authKeeper.StringToBytes(msg.Voter)
if err != nil {
Expand All @@ -162,6 +205,38 @@ func (k msgServer) Vote(goCtx context.Context, msg *v1.MsgVote) (*v1.MsgVoteResp

// VoteWeighted implements the MsgServer.VoteWeighted method.
func (k msgServer) VoteWeighted(goCtx context.Context, msg *v1.MsgVoteWeighted) (*v1.MsgVoteWeightedResponse, error) {
if _, err := sdk.AccAddressFromBech32(msg.Voter); err != nil {
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid voter address: %s", err)
}
if len(msg.Options) == 0 {
return nil, errors.Wrap(sdkerrors.ErrInvalidRequest, v1.WeightedVoteOptions(msg.Options).String())
}

totalWeight := math.LegacyNewDec(0)
usedOptions := make(map[v1.VoteOption]bool)
for _, option := range msg.Options {
if !option.IsValid() {
return nil, errors.Wrap(govtypes.ErrInvalidVote, option.String())
}
weight, err := sdk.NewDecFromStr(option.Weight)
if err != nil {
return nil, errors.Wrapf(govtypes.ErrInvalidVote, "invalid weight: %s", err)
}
totalWeight = totalWeight.Add(weight)
if usedOptions[option.Option] {
return nil, errors.Wrap(govtypes.ErrInvalidVote, "duplicated vote option")
}
usedOptions[option.Option] = true
}

if totalWeight.GT(math.LegacyNewDec(1)) {
return nil, errors.Wrap(govtypes.ErrInvalidVote, "total weight overflow 1.00")
}

if totalWeight.LT(math.LegacyNewDec(1)) {
return nil, errors.Wrap(govtypes.ErrInvalidVote, "total weight lower than 1.00")
}

ctx := sdk.UnwrapSDKContext(goCtx)
accAddr, accErr := k.authKeeper.StringToBytes(msg.Voter)
if accErr != nil {
Expand All @@ -185,6 +260,14 @@ func (k msgServer) VoteWeighted(goCtx context.Context, msg *v1.MsgVoteWeighted)

// Deposit implements the MsgServer.Deposit method.
func (k msgServer) Deposit(goCtx context.Context, msg *v1.MsgDeposit) (*v1.MsgDepositResponse, error) {
if _, err := sdk.AccAddressFromBech32(msg.Depositor); err != nil {
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid depositor address: %s", err)
}

if err := validateAmount(msg.Amount); err != nil {
return nil, err
}

ctx := sdk.UnwrapSDKContext(goCtx)
accAddr, err := k.authKeeper.StringToBytes(msg.Depositor)
if err != nil {
Expand Down Expand Up @@ -221,6 +304,10 @@ func (k msgServer) UpdateParams(goCtx context.Context, msg *v1.MsgUpdateParams)
return nil, errors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Authority)
}

if err := msg.Params.ValidateBasic(); err != nil {
return nil, err
}

ctx := sdk.UnwrapSDKContext(goCtx)
if err := k.SetParams(ctx, msg.Params); err != nil {
return nil, err
Expand All @@ -243,6 +330,17 @@ func NewLegacyMsgServerImpl(govAcct string, v1Server v1.MsgServer) v1beta1.MsgSe
var _ v1beta1.MsgServer = legacyMsgServer{}

func (k legacyMsgServer) SubmitProposal(goCtx context.Context, msg *v1beta1.MsgSubmitProposal) (*v1beta1.MsgSubmitProposalResponse, error) {
content := msg.GetContent()
if content == nil {
return nil, errors.Wrap(govtypes.ErrInvalidProposalContent, "missing content")
}
if !v1beta1.IsValidProposalType(content.ProposalType()) {
return nil, errors.Wrap(govtypes.ErrInvalidProposalType, content.ProposalType())
}
if err := content.ValidateBasic(); err != nil {
return nil, err
}

contentMsg, err := v1.NewLegacyContent(msg.GetContent(), k.govAcct)
if err != nil {
return nil, fmt.Errorf("error converting legacy content into proposal message: %w", err)
Expand Down Expand Up @@ -312,3 +410,36 @@ func (k legacyMsgServer) Deposit(goCtx context.Context, msg *v1beta1.MsgDeposit)
}
return &v1beta1.MsgDepositResponse{}, nil
}

func validateAmount(amount sdk.Coins) error {
if !amount.IsValid() {
return sdkerrors.ErrInvalidCoins.Wrap(amount.String())
}

if !amount.IsAllPositive() {
return sdkerrors.ErrInvalidCoins.Wrap(amount.String())
}

return nil
}

func validateMsgs(msg *v1.MsgSubmitProposal) error {
msgs, err := msg.GetMsgs()
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}

for idx, msg := range msgs {
m, ok := msg.(sdk.HasValidateBasic)
if !ok {
continue
}

if err := m.ValidateBasic(); err != nil {
return errors.Wrap(govtypes.ErrInvalidProposalMsg,
fmt.Sprintf("msg: %d, err: %s", idx, err.Error()))
}
}

return nil
}
Loading