2019-06-05 16:26:17 -07:00
|
|
|
package types
|
2018-01-12 11:49:53 -08:00
|
|
|
|
|
|
|
import (
|
2018-01-26 04:19:33 -08: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-01-12 11:49:53 -08:00
|
|
|
)
|
|
|
|
|
2020-05-26 09:52:23 -07:00
|
|
|
// bank message types
|
|
|
|
const (
|
|
|
|
TypeMsgSend = "send"
|
|
|
|
TypeMsgMultiSend = "multisend"
|
|
|
|
)
|
|
|
|
|
2020-06-03 12:52:05 -07:00
|
|
|
var _ sdk.Msg = &MsgSend{}
|
2018-03-02 09:21:49 -08:00
|
|
|
|
2018-04-18 21:49:24 -07:00
|
|
|
// NewMsgSend - construct arbitrary multi-in, multi-out send msg.
|
2020-06-03 12:52:05 -07:00
|
|
|
func NewMsgSend(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins) *MsgSend {
|
|
|
|
return &MsgSend{FromAddress: fromAddr, ToAddress: toAddr, Amount: amount}
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// Route Implements Msg.
|
2018-12-19 11:58:30 -08:00
|
|
|
func (msg MsgSend) Route() string { return RouterKey }
|
2018-01-12 11:49:53 -08:00
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// Type Implements Msg.
|
2020-05-26 09:52:23 -07:00
|
|
|
func (msg MsgSend) Type() string { return TypeMsgSend }
|
2019-02-08 13:35:19 -08:00
|
|
|
|
|
|
|
// ValidateBasic Implements Msg.
|
2019-12-27 09:57:54 -08:00
|
|
|
func (msg MsgSend) ValidateBasic() error {
|
2019-02-04 15:58:02 -08:00
|
|
|
if msg.FromAddress.Empty() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing sender address")
|
2019-02-04 15:58:02 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2019-02-04 15:58:02 -08:00
|
|
|
if msg.ToAddress.Empty() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing recipient address")
|
2019-02-04 15:58:02 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2019-02-27 13:09:26 -08:00
|
|
|
if !msg.Amount.IsValid() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String())
|
2019-02-27 13:09:26 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2019-02-15 07:33:23 -08:00
|
|
|
if !msg.Amount.IsAllPositive() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String())
|
2019-02-04 15:58:02 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2019-02-04 15:58:02 -08:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// GetSignBytes Implements Msg.
|
2019-02-04 15:58:02 -08:00
|
|
|
func (msg MsgSend) GetSignBytes() []byte {
|
2019-06-05 16:26:17 -07:00
|
|
|
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg))
|
2019-02-04 15:58:02 -08:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// GetSigners Implements Msg.
|
2019-02-04 15:58:02 -08:00
|
|
|
func (msg MsgSend) GetSigners() []sdk.AccAddress {
|
|
|
|
return []sdk.AccAddress{msg.FromAddress}
|
|
|
|
}
|
|
|
|
|
2020-06-03 12:52:05 -07:00
|
|
|
var _ sdk.Msg = &MsgMultiSend{}
|
2019-02-04 15:58:02 -08:00
|
|
|
|
|
|
|
// NewMsgMultiSend - construct arbitrary multi-in, multi-out send msg.
|
2020-06-03 12:52:05 -07:00
|
|
|
func NewMsgMultiSend(in []Input, out []Output) *MsgMultiSend {
|
|
|
|
return &MsgMultiSend{Inputs: in, Outputs: out}
|
2019-02-04 15:58:02 -08:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// Route Implements Msg
|
2019-02-04 15:58:02 -08:00
|
|
|
func (msg MsgMultiSend) Route() string { return RouterKey }
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// Type Implements Msg
|
2020-05-26 09:52:23 -07:00
|
|
|
func (msg MsgMultiSend) Type() string { return TypeMsgMultiSend }
|
2019-02-08 13:35:19 -08:00
|
|
|
|
|
|
|
// ValidateBasic Implements Msg.
|
2019-12-27 09:57:54 -08:00
|
|
|
func (msg MsgMultiSend) ValidateBasic() error {
|
2018-01-12 11:49:53 -08:00
|
|
|
// this just makes sure all the inputs and outputs are properly formatted,
|
|
|
|
// not that they actually have the money inside
|
|
|
|
if len(msg.Inputs) == 0 {
|
2019-12-27 09:57:54 -08:00
|
|
|
return ErrNoInputs
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2018-01-12 11:49:53 -08:00
|
|
|
if len(msg.Outputs) == 0 {
|
2019-12-27 09:57:54 -08:00
|
|
|
return ErrNoOutputs
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
2019-01-02 13:19:48 -08:00
|
|
|
|
|
|
|
return ValidateInputsOutputs(msg.Inputs, msg.Outputs)
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// GetSignBytes Implements Msg.
|
2019-02-04 15:58:02 -08:00
|
|
|
func (msg MsgMultiSend) GetSignBytes() []byte {
|
2019-06-05 16:26:17 -07:00
|
|
|
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg))
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// GetSigners Implements Msg.
|
2019-02-04 15:58:02 -08:00
|
|
|
func (msg MsgMultiSend) GetSigners() []sdk.AccAddress {
|
2018-07-06 00:06:53 -07:00
|
|
|
addrs := make([]sdk.AccAddress, len(msg.Inputs))
|
2018-01-12 11:49:53 -08:00
|
|
|
for i, in := range msg.Inputs {
|
|
|
|
addrs[i] = in.Address
|
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2018-01-12 11:49:53 -08:00
|
|
|
return addrs
|
|
|
|
}
|
|
|
|
|
|
|
|
// ValidateBasic - validate transaction input
|
2019-12-27 09:57:54 -08:00
|
|
|
func (in Input) ValidateBasic() error {
|
2018-01-12 11:49:53 -08:00
|
|
|
if len(in.Address) == 0 {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "input address missing")
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2018-01-12 11:49:53 -08:00
|
|
|
if !in.Coins.IsValid() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, in.Coins.String())
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2019-02-15 07:33:23 -08:00
|
|
|
if !in.Coins.IsAllPositive() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, in.Coins.String())
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2018-01-12 11:49:53 -08:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-02-04 15:58:02 -08:00
|
|
|
// NewInput - create a transaction input, used with MsgMultiSend
|
2018-07-06 00:06:53 -07:00
|
|
|
func NewInput(addr sdk.AccAddress, coins sdk.Coins) Input {
|
2019-01-23 00:46:41 -08:00
|
|
|
return Input{
|
2018-01-12 11:49:53 -08:00
|
|
|
Address: addr,
|
|
|
|
Coins: coins,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ValidateBasic - validate transaction output
|
2019-12-27 09:57:54 -08:00
|
|
|
func (out Output) ValidateBasic() error {
|
2018-01-12 11:49:53 -08:00
|
|
|
if len(out.Address) == 0 {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "output address missing")
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2018-01-12 11:49:53 -08:00
|
|
|
if !out.Coins.IsValid() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, out.Coins.String())
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2019-02-15 07:33:23 -08:00
|
|
|
if !out.Coins.IsAllPositive() {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, out.Coins.String())
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2018-01-12 11:49:53 -08:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-02-04 15:58:02 -08:00
|
|
|
// NewOutput - create a transaction output, used with MsgMultiSend
|
2018-07-06 00:06:53 -07:00
|
|
|
func NewOutput(addr sdk.AccAddress, coins sdk.Coins) Output {
|
2019-01-23 00:46:41 -08:00
|
|
|
return Output{
|
2018-01-12 11:49:53 -08:00
|
|
|
Address: addr,
|
|
|
|
Coins: coins,
|
|
|
|
}
|
|
|
|
}
|
2019-01-02 13:19:48 -08:00
|
|
|
|
|
|
|
// ValidateInputsOutputs validates that each respective input and output is
|
|
|
|
// valid and that the sum of inputs is equal to the sum of outputs.
|
2019-12-27 09:57:54 -08:00
|
|
|
func ValidateInputsOutputs(inputs []Input, outputs []Output) error {
|
2019-01-02 13:19:48 -08:00
|
|
|
var totalIn, totalOut sdk.Coins
|
|
|
|
|
|
|
|
for _, in := range inputs {
|
|
|
|
if err := in.ValidateBasic(); err != nil {
|
2019-12-27 09:57:54 -08:00
|
|
|
return err
|
2019-01-02 13:19:48 -08:00
|
|
|
}
|
2019-12-27 09:57:54 -08:00
|
|
|
|
2020-01-03 12:44:53 -08:00
|
|
|
totalIn = totalIn.Add(in.Coins...)
|
2019-01-02 13:19:48 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, out := range outputs {
|
|
|
|
if err := out.ValidateBasic(); err != nil {
|
2019-12-27 09:57:54 -08:00
|
|
|
return err
|
2019-01-02 13:19:48 -08:00
|
|
|
}
|
2019-12-27 09:57:54 -08:00
|
|
|
|
2020-01-03 12:44:53 -08:00
|
|
|
totalOut = totalOut.Add(out.Coins...)
|
2019-01-02 13:19:48 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// make sure inputs and outputs match
|
|
|
|
if !totalIn.IsEqual(totalOut) {
|
2019-12-27 09:57:54 -08:00
|
|
|
return ErrInputOutputMismatch
|
2019-01-02 13:19:48 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|