From 83bbf8ea3b98a9a8f1709bfa8dcf70fa9d169150 Mon Sep 17 00:00:00 2001 From: Lukasz Cwik Date: Thu, 14 Dec 2023 12:40:46 -0800 Subject: [PATCH] [CORE-843, CORE-538] Re-add ValidateBasic to MsgSubmitProposal Allow for messages to be validated during CheckTx. --- x/gov/types/v1/msgs.go | 54 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/x/gov/types/v1/msgs.go b/x/gov/types/v1/msgs.go index facfbfa9c2a2..9ccb0852724f 100644 --- a/x/gov/types/v1/msgs.go +++ b/x/gov/types/v1/msgs.go @@ -1,9 +1,15 @@ package v1 import ( + "fmt" + + errorsmod "cosmossdk.io/errors" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" sdktx "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" ) @@ -55,6 +61,54 @@ func (m *MsgSubmitProposal) SetMsgs(msgs []sdk.Msg) error { return nil } +// TODO(CORE-843): Revert this if we decide to move to only validate during `DeliverTx`. +// ValidateBasic implements the sdk.Msg interface. +func (m *MsgSubmitProposal) ValidateBasic() error { + if m.Title == "" { + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "proposal title cannot be empty") + } + if m.Summary == "" { + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "proposal summary cannot be empty") + } + + if _, err := sdk.AccAddressFromBech32(m.Proposer); err != nil { + return sdkerrors.ErrInvalidAddress.Wrapf("invalid proposer address: %s", err) + } + + deposit := sdk.NewCoins(m.InitialDeposit...) + if !deposit.IsValid() { + return errorsmod.Wrap(sdkerrors.ErrInvalidCoins, deposit.String()) + } + + if deposit.IsAnyNegative() { + return errorsmod.Wrap(sdkerrors.ErrInvalidCoins, deposit.String()) + } + + // Check that either metadata or Msgs length is non nil. + if len(m.Messages) == 0 && len(m.Metadata) == 0 { + return errorsmod.Wrap(types.ErrNoProposalMsgs, "either metadata or Msgs length must be non-nil") + } + + msgs, err := m.GetMsgs() + 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 errorsmod.Wrap(types.ErrInvalidProposalMsg, + fmt.Sprintf("msg: %d, err: %s", idx, err.Error())) + } + } + + return nil +} + // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (m MsgSubmitProposal) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { return sdktx.UnpackInterfaces(unpacker, m.Messages)