cosmos-sdk/x/gov/types/msgs.go

227 lines
5.9 KiB
Go

package types
import (
"fmt"
yaml "gopkg.in/yaml.v2"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
// Governance message types and routes
const (
TypeMsgDeposit = "deposit"
TypeMsgVote = "vote"
TypeMsgSubmitProposal = "submit_proposal"
)
var (
_, _, _ sdk.Msg = &MsgSubmitProposal{}, &MsgDeposit{}, &MsgVote{}
_ MsgSubmitProposalI = &MsgSubmitProposal{}
_ types.UnpackInterfacesMessage = &MsgSubmitProposal{}
)
// MsgSubmitProposalI defines the specific interface a concrete message must
// implement in order to process governance proposals. The concrete MsgSubmitProposal
// must be defined at the application-level.
type MsgSubmitProposalI interface {
sdk.Msg
GetContent() Content
SetContent(Content) error
GetInitialDeposit() sdk.Coins
SetInitialDeposit(sdk.Coins)
GetProposer() sdk.AccAddress
SetProposer(sdk.AccAddress)
}
// NewMsgSubmitProposal creates a new MsgSubmitProposal.
func NewMsgSubmitProposal(content Content, initialDeposit sdk.Coins, proposer sdk.AccAddress) (*MsgSubmitProposal, error) {
m := &MsgSubmitProposal{
InitialDeposit: initialDeposit,
Proposer: proposer,
}
err := m.SetContent(content)
if err != nil {
return nil, err
}
return m, nil
}
func (m *MsgSubmitProposal) GetInitialDeposit() sdk.Coins { return m.InitialDeposit }
func (m *MsgSubmitProposal) GetProposer() sdk.AccAddress { return m.Proposer }
func (m *MsgSubmitProposal) GetContent() Content {
content, ok := m.Content.GetCachedValue().(Content)
if !ok {
return nil
}
return content
}
func (m *MsgSubmitProposal) SetInitialDeposit(coins sdk.Coins) {
m.InitialDeposit = coins
}
func (m *MsgSubmitProposal) SetProposer(address sdk.AccAddress) {
m.Proposer = address
}
func (m *MsgSubmitProposal) SetContent(content Content) error {
msg, ok := content.(proto.Message)
if !ok {
return fmt.Errorf("can't proto marshal %T", msg)
}
any, err := types.NewAnyWithValue(msg)
if err != nil {
return err
}
m.Content = any
return nil
}
// Route implements Msg
func (m MsgSubmitProposal) Route() string { return RouterKey }
// Type implements Msg
func (m MsgSubmitProposal) Type() string { return TypeMsgSubmitProposal }
// ValidateBasic implements Msg
func (m MsgSubmitProposal) ValidateBasic() error {
if m.Proposer.Empty() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, m.Proposer.String())
}
if !m.InitialDeposit.IsValid() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.InitialDeposit.String())
}
if m.InitialDeposit.IsAnyNegative() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.InitialDeposit.String())
}
content := m.GetContent()
if content == nil {
return sdkerrors.Wrap(ErrInvalidProposalContent, "missing content")
}
if !IsValidProposalType(content.ProposalType()) {
return sdkerrors.Wrap(ErrInvalidProposalType, content.ProposalType())
}
if err := content.ValidateBasic(); err != nil {
return err
}
return nil
}
// GetSignBytes implements Msg
func (m MsgSubmitProposal) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(m)
return sdk.MustSortJSON(bz)
}
// GetSigners implements Msg
func (m MsgSubmitProposal) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{m.Proposer}
}
// String implements the Stringer interface
func (m MsgSubmitProposal) String() string {
out, _ := yaml.Marshal(m)
return string(out)
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (m MsgSubmitProposal) UnpackInterfaces(unpacker types.AnyUnpacker) error {
var content Content
return unpacker.UnpackAny(m.Content, &content)
}
// NewMsgDeposit creates a new MsgDeposit instance
func NewMsgDeposit(depositor sdk.AccAddress, proposalID uint64, amount sdk.Coins) *MsgDeposit {
return &MsgDeposit{proposalID, depositor, amount}
}
// Route implements Msg
func (msg MsgDeposit) Route() string { return RouterKey }
// Type implements Msg
func (msg MsgDeposit) Type() string { return TypeMsgDeposit }
// ValidateBasic implements Msg
func (msg MsgDeposit) ValidateBasic() error {
if msg.Depositor.Empty() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Depositor.String())
}
if !msg.Amount.IsValid() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String())
}
if msg.Amount.IsAnyNegative() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String())
}
return nil
}
// String implements the Stringer interface
func (msg MsgDeposit) String() string {
out, _ := yaml.Marshal(msg)
return string(out)
}
// GetSignBytes implements Msg
func (msg MsgDeposit) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// GetSigners implements Msg
func (msg MsgDeposit) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{msg.Depositor}
}
// NewMsgVote creates a message to cast a vote on an active proposal
func NewMsgVote(voter sdk.AccAddress, proposalID uint64, option VoteOption) *MsgVote {
return &MsgVote{proposalID, voter, option}
}
// Route implements Msg
func (msg MsgVote) Route() string { return RouterKey }
// Type implements Msg
func (msg MsgVote) Type() string { return TypeMsgVote }
// ValidateBasic implements Msg
func (msg MsgVote) ValidateBasic() error {
if msg.Voter.Empty() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Voter.String())
}
if !ValidVoteOption(msg.Option) {
return sdkerrors.Wrap(ErrInvalidVote, msg.Option.String())
}
return nil
}
// String implements the Stringer interface
func (msg MsgVote) String() string {
out, _ := yaml.Marshal(msg)
return string(out)
}
// GetSignBytes implements Msg
func (msg MsgVote) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// GetSigners implements Msg
func (msg MsgVote) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{msg.Voter}
}