2019-04-30 09:31:38 -07:00
|
|
|
package types
|
2018-06-21 17:19:14 -07:00
|
|
|
|
|
|
|
import (
|
2020-05-19 13:17:29 -07:00
|
|
|
"fmt"
|
2018-06-21 17:19:14 -07:00
|
|
|
|
2020-05-19 13:17:29 -07:00
|
|
|
yaml "gopkg.in/yaml.v2"
|
|
|
|
|
|
|
|
"github.com/gogo/protobuf/proto"
|
|
|
|
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec/types"
|
2018-06-21 17:19:14 -07:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2019-12-27 09:57:54 -08:00
|
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
2018-06-21 17:19:14 -07:00
|
|
|
)
|
|
|
|
|
2018-12-14 11:13:43 -08:00
|
|
|
// Governance message types and routes
|
|
|
|
const (
|
|
|
|
TypeMsgDeposit = "deposit"
|
|
|
|
TypeMsgVote = "vote"
|
|
|
|
TypeMsgSubmitProposal = "submit_proposal"
|
|
|
|
)
|
2018-06-21 17:19:14 -07:00
|
|
|
|
2020-05-19 13:17:29 -07:00
|
|
|
var (
|
2020-06-03 12:52:05 -07:00
|
|
|
_, _, _ sdk.Msg = &MsgSubmitProposal{}, &MsgDeposit{}, &MsgVote{}
|
2020-05-19 13:17:29 -07:00
|
|
|
_ MsgSubmitProposalI = &MsgSubmitProposal{}
|
2020-06-03 12:52:05 -07:00
|
|
|
_ types.UnpackInterfacesMessage = &MsgSubmitProposal{}
|
2020-05-19 13:17:29 -07:00
|
|
|
)
|
2018-09-17 07:34:06 -07:00
|
|
|
|
2020-03-02 13:29:10 -08:00
|
|
|
// MsgSubmitProposalI defines the specific interface a concrete message must
|
2020-03-02 11:13:42 -08:00
|
|
|
// implement in order to process governance proposals. The concrete MsgSubmitProposal
|
|
|
|
// must be defined at the application-level.
|
2020-03-02 13:29:10 -08:00
|
|
|
type MsgSubmitProposalI interface {
|
2020-03-02 11:13:42 -08:00
|
|
|
sdk.Msg
|
|
|
|
|
|
|
|
GetContent() Content
|
2020-04-14 12:05:14 -07:00
|
|
|
SetContent(Content) error
|
|
|
|
|
2020-03-02 11:13:42 -08:00
|
|
|
GetInitialDeposit() sdk.Coins
|
2020-04-14 12:05:14 -07:00
|
|
|
SetInitialDeposit(sdk.Coins)
|
|
|
|
|
2020-03-02 11:13:42 -08:00
|
|
|
GetProposer() sdk.AccAddress
|
2020-04-14 12:05:14 -07:00
|
|
|
SetProposer(sdk.AccAddress)
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2020-05-19 13:17:29 -07:00
|
|
|
// NewMsgSubmitProposal creates a new MsgSubmitProposal.
|
|
|
|
func NewMsgSubmitProposal(content Content, initialDeposit sdk.Coins, proposer sdk.AccAddress) (*MsgSubmitProposal, error) {
|
|
|
|
m := &MsgSubmitProposal{
|
2020-03-02 11:13:42 -08:00
|
|
|
InitialDeposit: initialDeposit,
|
|
|
|
Proposer: proposer,
|
|
|
|
}
|
2020-05-19 13:17:29 -07:00
|
|
|
err := m.SetContent(content)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return m, nil
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2020-05-19 13:17:29 -07:00
|
|
|
func (m *MsgSubmitProposal) GetInitialDeposit() sdk.Coins { return m.InitialDeposit }
|
2020-04-14 12:05:14 -07:00
|
|
|
|
2020-05-19 13:17:29 -07:00
|
|
|
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
|
|
|
|
}
|
2020-04-14 12:05:14 -07:00
|
|
|
|
2020-05-19 13:17:29 -07:00
|
|
|
func (m *MsgSubmitProposal) SetInitialDeposit(coins sdk.Coins) {
|
|
|
|
m.InitialDeposit = coins
|
2020-04-14 12:05:14 -07:00
|
|
|
}
|
|
|
|
|
2020-05-19 13:17:29 -07:00
|
|
|
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
|
2020-04-14 12:05:14 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// Route implements Msg
|
2020-05-19 13:17:29 -07:00
|
|
|
func (m MsgSubmitProposal) Route() string { return RouterKey }
|
2018-06-21 17:19:14 -07:00
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// Type implements Msg
|
2020-05-19 13:17:29 -07:00
|
|
|
func (m MsgSubmitProposal) Type() string { return TypeMsgSubmitProposal }
|
2019-08-08 12:51:18 -07:00
|
|
|
|
|
|
|
// ValidateBasic implements Msg
|
2020-05-19 13:17:29 -07:00
|
|
|
func (m MsgSubmitProposal) ValidateBasic() error {
|
|
|
|
if m.Proposer.Empty() {
|
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, m.Proposer.String())
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
2020-05-19 13:17:29 -07:00
|
|
|
if !m.InitialDeposit.IsValid() {
|
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.InitialDeposit.String())
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
2020-05-19 13:17:29 -07:00
|
|
|
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
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2020-03-02 11:13:42 -08:00
|
|
|
return nil
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// GetSignBytes implements Msg
|
2020-05-19 13:17:29 -07:00
|
|
|
func (m MsgSubmitProposal) GetSignBytes() []byte {
|
|
|
|
bz := ModuleCdc.MustMarshalJSON(m)
|
2019-01-23 00:46:41 -08:00
|
|
|
return sdk.MustSortJSON(bz)
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// GetSigners implements Msg
|
2020-05-19 13:17:29 -07:00
|
|
|
func (m MsgSubmitProposal) GetSigners() []sdk.AccAddress {
|
|
|
|
return []sdk.AccAddress{m.Proposer}
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2020-03-02 11:13:42 -08:00
|
|
|
// String implements the Stringer interface
|
2020-05-19 13:17:29 -07:00
|
|
|
func (m MsgSubmitProposal) String() string {
|
|
|
|
out, _ := yaml.Marshal(m)
|
2020-03-02 11:13:42 -08:00
|
|
|
return string(out)
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:17:29 -07:00
|
|
|
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
|
|
|
func (m MsgSubmitProposal) UnpackInterfaces(unpacker types.AnyUnpacker) error {
|
|
|
|
var content Content
|
|
|
|
return unpacker.UnpackAny(m.Content, &content)
|
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// NewMsgDeposit creates a new MsgDeposit instance
|
2020-06-03 12:52:05 -07:00
|
|
|
func NewMsgDeposit(depositor sdk.AccAddress, proposalID uint64, amount sdk.Coins) *MsgDeposit {
|
|
|
|
return &MsgDeposit{proposalID, depositor, amount}
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// Route implements Msg
|
2018-12-19 11:58:30 -08:00
|
|
|
func (msg MsgDeposit) Route() string { return RouterKey }
|
2018-06-21 17:19:14 -07:00
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// Type implements Msg
|
|
|
|
func (msg MsgDeposit) Type() string { return TypeMsgDeposit }
|
|
|
|
|
|
|
|
// ValidateBasic implements Msg
|
2019-12-27 09:57:54 -08:00
|
|
|
func (msg MsgDeposit) ValidateBasic() error {
|
2019-02-08 18:33:06 -08:00
|
|
|
if msg.Depositor.Empty() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Depositor.String())
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
if !msg.Amount.IsValid() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String())
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
2019-02-06 14:45:15 -08:00
|
|
|
if msg.Amount.IsAnyNegative() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String())
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
2019-04-30 09:31:38 -07:00
|
|
|
|
2018-06-21 17:19:14 -07:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// String implements the Stringer interface
|
2018-06-21 17:19:14 -07:00
|
|
|
func (msg MsgDeposit) String() string {
|
2020-03-02 11:13:42 -08:00
|
|
|
out, _ := yaml.Marshal(msg)
|
|
|
|
return string(out)
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// GetSignBytes implements Msg
|
2018-06-21 17:19:14 -07:00
|
|
|
func (msg MsgDeposit) GetSignBytes() []byte {
|
2019-05-16 08:25:32 -07:00
|
|
|
bz := ModuleCdc.MustMarshalJSON(msg)
|
2019-01-23 00:46:41 -08:00
|
|
|
return sdk.MustSortJSON(bz)
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// GetSigners implements Msg
|
2018-07-06 00:06:53 -07:00
|
|
|
func (msg MsgDeposit) GetSigners() []sdk.AccAddress {
|
2018-11-21 15:53:33 -08:00
|
|
|
return []sdk.AccAddress{msg.Depositor}
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// NewMsgVote creates a message to cast a vote on an active proposal
|
2020-06-03 12:52:05 -07:00
|
|
|
func NewMsgVote(voter sdk.AccAddress, proposalID uint64, option VoteOption) *MsgVote {
|
|
|
|
return &MsgVote{proposalID, voter, option}
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// Route implements Msg
|
2018-12-19 11:58:30 -08:00
|
|
|
func (msg MsgVote) Route() string { return RouterKey }
|
2018-06-21 17:19:14 -07:00
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// Type implements Msg
|
|
|
|
func (msg MsgVote) Type() string { return TypeMsgVote }
|
|
|
|
|
|
|
|
// ValidateBasic implements Msg
|
2019-12-27 09:57:54 -08:00
|
|
|
func (msg MsgVote) ValidateBasic() error {
|
2019-02-08 15:54:40 -08:00
|
|
|
if msg.Voter.Empty() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Voter.String())
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
2019-04-30 09:31:38 -07:00
|
|
|
if !ValidVoteOption(msg.Option) {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(ErrInvalidVote, msg.Option.String())
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
2019-04-30 09:31:38 -07:00
|
|
|
|
2018-06-21 17:19:14 -07:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// String implements the Stringer interface
|
2018-06-21 17:19:14 -07:00
|
|
|
func (msg MsgVote) String() string {
|
2020-03-02 11:13:42 -08:00
|
|
|
out, _ := yaml.Marshal(msg)
|
|
|
|
return string(out)
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// GetSignBytes implements Msg
|
2018-06-21 17:19:14 -07:00
|
|
|
func (msg MsgVote) GetSignBytes() []byte {
|
2019-05-16 08:25:32 -07:00
|
|
|
bz := ModuleCdc.MustMarshalJSON(msg)
|
2019-01-23 00:46:41 -08:00
|
|
|
return sdk.MustSortJSON(bz)
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 12:51:18 -07:00
|
|
|
// GetSigners implements Msg
|
2018-07-06 00:06:53 -07:00
|
|
|
func (msg MsgVote) GetSigners() []sdk.AccAddress {
|
|
|
|
return []sdk.AccAddress{msg.Voter}
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|