cosmos-sdk/x/staking/types/msg.go

276 lines
8.0 KiB
Go

package types
import (
"bytes"
"github.com/tendermint/tendermint/crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
var (
_ sdk.Msg = &MsgCreateValidator{}
_ sdk.Msg = &MsgEditValidator{}
_ sdk.Msg = &MsgDelegate{}
_ sdk.Msg = &MsgUndelegate{}
_ sdk.Msg = &MsgBeginRedelegate{}
)
// NewMsgCreateValidator creates a new MsgCreateValidator instance.
// Delegator address and validator address are the same.
func NewMsgCreateValidator(
valAddr sdk.ValAddress, pubKey crypto.PubKey, selfDelegation sdk.Coin,
description Description, commission CommissionRates, minSelfDelegation sdk.Int,
) MsgCreateValidator {
var pkStr string
if pubKey != nil {
pkStr = sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, pubKey)
}
return MsgCreateValidator{
Description: description,
DelegatorAddress: sdk.AccAddress(valAddr),
ValidatorAddress: valAddr,
Pubkey: pkStr,
Value: selfDelegation,
Commission: commission,
MinSelfDelegation: minSelfDelegation,
}
}
// Route implements the sdk.Msg interface.
func (msg MsgCreateValidator) Route() string { return RouterKey }
// Type implements the sdk.Msg interface.
func (msg MsgCreateValidator) Type() string { return "create_validator" }
// GetSigners implements the sdk.Msg interface. It returns the address(es) that
// must sign over msg.GetSignBytes().
// If the validator address is not same as delegator's, then the validator must
// sign the msg as well.
func (msg MsgCreateValidator) GetSigners() []sdk.AccAddress {
// delegator is first signer so delegator pays fees
addrs := []sdk.AccAddress{msg.DelegatorAddress}
if !bytes.Equal(msg.DelegatorAddress.Bytes(), msg.ValidatorAddress.Bytes()) {
addrs = append(addrs, sdk.AccAddress(msg.ValidatorAddress))
}
return addrs
}
// GetSignBytes returns the message bytes to sign over.
func (msg MsgCreateValidator) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// ValidateBasic implements the sdk.Msg interface.
func (msg MsgCreateValidator) ValidateBasic() error {
// note that unmarshaling from bech32 ensures either empty or valid
if msg.DelegatorAddress.Empty() {
return ErrEmptyDelegatorAddr
}
if msg.ValidatorAddress.Empty() {
return ErrEmptyValidatorAddr
}
if !sdk.AccAddress(msg.ValidatorAddress).Equals(msg.DelegatorAddress) {
return ErrBadValidatorAddr
}
if msg.Pubkey == "" {
return ErrEmptyValidatorPubKey
}
if !msg.Value.Amount.IsPositive() {
return ErrBadDelegationAmount
}
if msg.Description == (Description{}) {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description")
}
if msg.Commission == (CommissionRates{}) {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty commission")
}
if err := msg.Commission.Validate(); err != nil {
return err
}
if !msg.MinSelfDelegation.IsPositive() {
return ErrMinSelfDelegationInvalid
}
if msg.Value.Amount.LT(msg.MinSelfDelegation) {
return ErrSelfDelegationBelowMinimum
}
return nil
}
// NewMsgEditValidator creates a new MsgEditValidator instance
func NewMsgEditValidator(valAddr sdk.ValAddress, description Description, newRate *sdk.Dec, newMinSelfDelegation *sdk.Int) MsgEditValidator {
return MsgEditValidator{
Description: description,
CommissionRate: newRate,
ValidatorAddress: valAddr,
MinSelfDelegation: newMinSelfDelegation,
}
}
// Route implements the sdk.Msg interface.
func (msg MsgEditValidator) Route() string { return RouterKey }
// Type implements the sdk.Msg interface.
func (msg MsgEditValidator) Type() string { return "edit_validator" }
// GetSigners implements the sdk.Msg interface.
func (msg MsgEditValidator) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{sdk.AccAddress(msg.ValidatorAddress)}
}
// GetSignBytes implements the sdk.Msg interface.
func (msg MsgEditValidator) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// ValidateBasic implements the sdk.Msg interface.
func (msg MsgEditValidator) ValidateBasic() error {
if msg.ValidatorAddress.Empty() {
return ErrEmptyValidatorAddr
}
if msg.Description == (Description{}) {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description")
}
if msg.MinSelfDelegation != nil && !msg.MinSelfDelegation.IsPositive() {
return ErrMinSelfDelegationInvalid
}
if msg.CommissionRate != nil {
if msg.CommissionRate.GT(sdk.OneDec()) || msg.CommissionRate.IsNegative() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "commission rate must be between 0 and 1 (inclusive)")
}
}
return nil
}
// NewMsgDelegate creates a new MsgDelegate instance.
func NewMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Coin) MsgDelegate {
return MsgDelegate{
DelegatorAddress: delAddr,
ValidatorAddress: valAddr,
Amount: amount,
}
}
// Route implements the sdk.Msg interface.
func (msg MsgDelegate) Route() string { return RouterKey }
// Type implements the sdk.Msg interface.
func (msg MsgDelegate) Type() string { return "delegate" }
// GetSigners implements the sdk.Msg interface.
func (msg MsgDelegate) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{msg.DelegatorAddress}
}
// GetSignBytes implements the sdk.Msg interface.
func (msg MsgDelegate) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// ValidateBasic implements the sdk.Msg interface.
func (msg MsgDelegate) ValidateBasic() error {
if msg.DelegatorAddress.Empty() {
return ErrEmptyDelegatorAddr
}
if msg.ValidatorAddress.Empty() {
return ErrEmptyValidatorAddr
}
if !msg.Amount.Amount.IsPositive() {
return ErrBadDelegationAmount
}
return nil
}
// NewMsgBeginRedelegate creates a new MsgBeginRedelegate instance.
func NewMsgBeginRedelegate(
delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, amount sdk.Coin,
) MsgBeginRedelegate {
return MsgBeginRedelegate{
DelegatorAddress: delAddr,
ValidatorSrcAddress: valSrcAddr,
ValidatorDstAddress: valDstAddr,
Amount: amount,
}
}
// Route implements the sdk.Msg interface.
func (msg MsgBeginRedelegate) Route() string { return RouterKey }
// Type implements the sdk.Msg interface
func (msg MsgBeginRedelegate) Type() string { return "begin_redelegate" }
// GetSigners implements the sdk.Msg interface
func (msg MsgBeginRedelegate) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{msg.DelegatorAddress}
}
// GetSignBytes implements the sdk.Msg interface.
func (msg MsgBeginRedelegate) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// ValidateBasic implements the sdk.Msg interface.
func (msg MsgBeginRedelegate) ValidateBasic() error {
if msg.DelegatorAddress.Empty() {
return ErrEmptyDelegatorAddr
}
if msg.ValidatorSrcAddress.Empty() {
return ErrEmptyValidatorAddr
}
if msg.ValidatorDstAddress.Empty() {
return ErrEmptyValidatorAddr
}
if !msg.Amount.Amount.IsPositive() {
return ErrBadSharesAmount
}
return nil
}
// NewMsgUndelegate creates a new MsgUndelegate instance.
func NewMsgUndelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Coin) MsgUndelegate {
return MsgUndelegate{
DelegatorAddress: delAddr,
ValidatorAddress: valAddr,
Amount: amount,
}
}
// Route implements the sdk.Msg interface.
func (msg MsgUndelegate) Route() string { return RouterKey }
// Type implements the sdk.Msg interface.
func (msg MsgUndelegate) Type() string { return "begin_unbonding" }
// GetSigners implements the sdk.Msg interface.
func (msg MsgUndelegate) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.DelegatorAddress} }
// GetSignBytes implements the sdk.Msg interface.
func (msg MsgUndelegate) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// ValidateBasic implements the sdk.Msg interface.
func (msg MsgUndelegate) ValidateBasic() error {
if msg.DelegatorAddress.Empty() {
return ErrEmptyDelegatorAddr
}
if msg.ValidatorAddress.Empty() {
return ErrEmptyValidatorAddr
}
if !msg.Amount.Amount.IsPositive() {
return ErrBadSharesAmount
}
return nil
}