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 }