github.com/Finschia/finschia-sdk@v0.48.1/x/staking/types/msg.go (about)

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  
     6  	codectypes "github.com/Finschia/finschia-sdk/codec/types"
     7  	cryptotypes "github.com/Finschia/finschia-sdk/crypto/types"
     8  	sdk "github.com/Finschia/finschia-sdk/types"
     9  	sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
    10  )
    11  
    12  // staking message types
    13  const (
    14  	TypeMsgUndelegate      = "begin_unbonding"
    15  	TypeMsgEditValidator   = "edit_validator"
    16  	TypeMsgCreateValidator = "create_validator"
    17  	TypeMsgDelegate        = "delegate"
    18  	TypeMsgBeginRedelegate = "begin_redelegate"
    19  )
    20  
    21  var (
    22  	_ sdk.Msg                            = &MsgCreateValidator{}
    23  	_ codectypes.UnpackInterfacesMessage = (*MsgCreateValidator)(nil)
    24  	_ sdk.Msg                            = &MsgCreateValidator{}
    25  	_ sdk.Msg                            = &MsgEditValidator{}
    26  	_ sdk.Msg                            = &MsgDelegate{}
    27  	_ sdk.Msg                            = &MsgUndelegate{}
    28  	_ sdk.Msg                            = &MsgBeginRedelegate{}
    29  )
    30  
    31  // NewMsgCreateValidator creates a new MsgCreateValidator instance.
    32  // Delegator address and validator address are the same.
    33  func NewMsgCreateValidator(
    34  	valAddr sdk.ValAddress, pubKey cryptotypes.PubKey, //nolint:interfacer
    35  	selfDelegation sdk.Coin, description Description, commission CommissionRates, minSelfDelegation sdk.Int,
    36  ) (*MsgCreateValidator, error) {
    37  	var pkAny *codectypes.Any
    38  	if pubKey != nil {
    39  		var err error
    40  		if pkAny, err = codectypes.NewAnyWithValue(pubKey); err != nil {
    41  			return nil, err
    42  		}
    43  	}
    44  	return &MsgCreateValidator{
    45  		Description:       description,
    46  		DelegatorAddress:  sdk.AccAddress(valAddr).String(),
    47  		ValidatorAddress:  valAddr.String(),
    48  		Pubkey:            pkAny,
    49  		Value:             selfDelegation,
    50  		Commission:        commission,
    51  		MinSelfDelegation: minSelfDelegation,
    52  	}, nil
    53  }
    54  
    55  // Route implements the sdk.Msg interface.
    56  func (msg MsgCreateValidator) Route() string { return RouterKey }
    57  
    58  // Type implements the sdk.Msg interface.
    59  func (msg MsgCreateValidator) Type() string { return TypeMsgCreateValidator }
    60  
    61  // GetSigners implements the sdk.Msg interface. It returns the address(es) that
    62  // must sign over msg.GetSignBytes().
    63  // If the validator address is not same as delegator's, then the validator must
    64  // sign the msg as well.
    65  func (msg MsgCreateValidator) GetSigners() []sdk.AccAddress {
    66  	// delegator is first signer so delegator pays fees
    67  	delAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddress)
    68  	if err != nil {
    69  		panic(err)
    70  	}
    71  	addrs := []sdk.AccAddress{delAddr}
    72  	addr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
    73  	if err != nil {
    74  		panic(err)
    75  	}
    76  	if !bytes.Equal(delAddr.Bytes(), addr.Bytes()) {
    77  		addrs = append(addrs, sdk.AccAddress(addr))
    78  	}
    79  
    80  	return addrs
    81  }
    82  
    83  // GetSignBytes returns the message bytes to sign over.
    84  func (msg MsgCreateValidator) GetSignBytes() []byte {
    85  	bz := ModuleCdc.MustMarshalJSON(&msg)
    86  	return sdk.MustSortJSON(bz)
    87  }
    88  
    89  // ValidateBasic implements the sdk.Msg interface.
    90  func (msg MsgCreateValidator) ValidateBasic() error {
    91  	// note that unmarshaling from bech32 ensures either empty or valid
    92  	delAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddress)
    93  	if err != nil {
    94  		return err
    95  	}
    96  	if delAddr.Empty() {
    97  		return ErrEmptyDelegatorAddr
    98  	}
    99  
   100  	if msg.ValidatorAddress == "" {
   101  		return ErrEmptyValidatorAddr
   102  	}
   103  
   104  	valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
   105  	if err != nil {
   106  		return err
   107  	}
   108  	if !sdk.AccAddress(valAddr).Equals(delAddr) {
   109  		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "validator address is invalid")
   110  	}
   111  
   112  	if msg.Pubkey == nil {
   113  		return ErrEmptyValidatorPubKey
   114  	}
   115  
   116  	if !msg.Value.IsValid() || !msg.Value.Amount.IsPositive() {
   117  		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid delegation amount")
   118  	}
   119  
   120  	if msg.Description == (Description{}) {
   121  		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description")
   122  	}
   123  
   124  	if msg.Commission == (CommissionRates{}) {
   125  		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty commission")
   126  	}
   127  
   128  	if err := msg.Commission.Validate(); err != nil {
   129  		return err
   130  	}
   131  
   132  	if !msg.MinSelfDelegation.IsPositive() {
   133  		return sdkerrors.Wrap(
   134  			sdkerrors.ErrInvalidRequest,
   135  			"minimum self delegation must be a positive integer",
   136  		)
   137  	}
   138  
   139  	if msg.Value.Amount.LT(msg.MinSelfDelegation) {
   140  		return ErrSelfDelegationBelowMinimum
   141  	}
   142  
   143  	return nil
   144  }
   145  
   146  // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
   147  func (msg MsgCreateValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
   148  	var pubKey cryptotypes.PubKey
   149  	return unpacker.UnpackAny(msg.Pubkey, &pubKey)
   150  }
   151  
   152  // NewMsgEditValidator creates a new MsgEditValidator instance
   153  //
   154  //nolint:interfacer
   155  func NewMsgEditValidator(valAddr sdk.ValAddress, description Description, newRate *sdk.Dec, newMinSelfDelegation *sdk.Int) *MsgEditValidator {
   156  	return &MsgEditValidator{
   157  		Description:       description,
   158  		CommissionRate:    newRate,
   159  		ValidatorAddress:  valAddr.String(),
   160  		MinSelfDelegation: newMinSelfDelegation,
   161  	}
   162  }
   163  
   164  // Route implements the sdk.Msg interface.
   165  func (msg MsgEditValidator) Route() string { return RouterKey }
   166  
   167  // Type implements the sdk.Msg interface.
   168  func (msg MsgEditValidator) Type() string { return TypeMsgEditValidator }
   169  
   170  // GetSigners implements the sdk.Msg interface.
   171  func (msg MsgEditValidator) GetSigners() []sdk.AccAddress {
   172  	valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
   173  	if err != nil {
   174  		panic(err)
   175  	}
   176  	return []sdk.AccAddress{valAddr.Bytes()}
   177  }
   178  
   179  // GetSignBytes implements the sdk.Msg interface.
   180  func (msg MsgEditValidator) GetSignBytes() []byte {
   181  	bz := ModuleCdc.MustMarshalJSON(&msg)
   182  	return sdk.MustSortJSON(bz)
   183  }
   184  
   185  // ValidateBasic implements the sdk.Msg interface.
   186  func (msg MsgEditValidator) ValidateBasic() error {
   187  	if msg.ValidatorAddress == "" {
   188  		return ErrEmptyValidatorAddr
   189  	}
   190  
   191  	if msg.Description == (Description{}) {
   192  		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description")
   193  	}
   194  
   195  	if msg.MinSelfDelegation != nil && !msg.MinSelfDelegation.IsPositive() {
   196  		return sdkerrors.Wrap(
   197  			sdkerrors.ErrInvalidRequest,
   198  			"minimum self delegation must be a positive integer",
   199  		)
   200  	}
   201  
   202  	if msg.CommissionRate != nil {
   203  		if msg.CommissionRate.GT(sdk.OneDec()) || msg.CommissionRate.IsNegative() {
   204  			return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "commission rate must be between 0 and 1 (inclusive)")
   205  		}
   206  	}
   207  
   208  	return nil
   209  }
   210  
   211  // NewMsgDelegate creates a new MsgDelegate instance.
   212  //
   213  //nolint:interfacer
   214  func NewMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Coin) *MsgDelegate {
   215  	return &MsgDelegate{
   216  		DelegatorAddress: delAddr.String(),
   217  		ValidatorAddress: valAddr.String(),
   218  		Amount:           amount,
   219  	}
   220  }
   221  
   222  // Route implements the sdk.Msg interface.
   223  func (msg MsgDelegate) Route() string { return RouterKey }
   224  
   225  // Type implements the sdk.Msg interface.
   226  func (msg MsgDelegate) Type() string { return TypeMsgDelegate }
   227  
   228  // GetSigners implements the sdk.Msg interface.
   229  func (msg MsgDelegate) GetSigners() []sdk.AccAddress {
   230  	delAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddress)
   231  	if err != nil {
   232  		panic(err)
   233  	}
   234  	return []sdk.AccAddress{delAddr}
   235  }
   236  
   237  // GetSignBytes implements the sdk.Msg interface.
   238  func (msg MsgDelegate) GetSignBytes() []byte {
   239  	bz := ModuleCdc.MustMarshalJSON(&msg)
   240  	return sdk.MustSortJSON(bz)
   241  }
   242  
   243  // ValidateBasic implements the sdk.Msg interface.
   244  func (msg MsgDelegate) ValidateBasic() error {
   245  	if msg.DelegatorAddress == "" {
   246  		return ErrEmptyDelegatorAddr
   247  	}
   248  
   249  	if msg.ValidatorAddress == "" {
   250  		return ErrEmptyValidatorAddr
   251  	}
   252  
   253  	if !msg.Amount.IsValid() || !msg.Amount.Amount.IsPositive() {
   254  		return sdkerrors.Wrap(
   255  			sdkerrors.ErrInvalidRequest,
   256  			"invalid delegation amount",
   257  		)
   258  	}
   259  
   260  	return nil
   261  }
   262  
   263  // NewMsgBeginRedelegate creates a new MsgBeginRedelegate instance.
   264  //
   265  //nolint:interfacer
   266  func NewMsgBeginRedelegate(
   267  	delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, amount sdk.Coin,
   268  ) *MsgBeginRedelegate {
   269  	return &MsgBeginRedelegate{
   270  		DelegatorAddress:    delAddr.String(),
   271  		ValidatorSrcAddress: valSrcAddr.String(),
   272  		ValidatorDstAddress: valDstAddr.String(),
   273  		Amount:              amount,
   274  	}
   275  }
   276  
   277  // Route implements the sdk.Msg interface.
   278  func (msg MsgBeginRedelegate) Route() string { return RouterKey }
   279  
   280  // Type implements the sdk.Msg interface
   281  func (msg MsgBeginRedelegate) Type() string { return TypeMsgBeginRedelegate }
   282  
   283  // GetSigners implements the sdk.Msg interface
   284  func (msg MsgBeginRedelegate) GetSigners() []sdk.AccAddress {
   285  	delAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddress)
   286  	if err != nil {
   287  		panic(err)
   288  	}
   289  	return []sdk.AccAddress{delAddr}
   290  }
   291  
   292  // GetSignBytes implements the sdk.Msg interface.
   293  func (msg MsgBeginRedelegate) GetSignBytes() []byte {
   294  	bz := ModuleCdc.MustMarshalJSON(&msg)
   295  	return sdk.MustSortJSON(bz)
   296  }
   297  
   298  // ValidateBasic implements the sdk.Msg interface.
   299  func (msg MsgBeginRedelegate) ValidateBasic() error {
   300  	if msg.DelegatorAddress == "" {
   301  		return ErrEmptyDelegatorAddr
   302  	}
   303  
   304  	if msg.ValidatorSrcAddress == "" {
   305  		return ErrEmptyValidatorAddr
   306  	}
   307  
   308  	if msg.ValidatorDstAddress == "" {
   309  		return ErrEmptyValidatorAddr
   310  	}
   311  
   312  	if !msg.Amount.IsValid() || !msg.Amount.Amount.IsPositive() {
   313  		return sdkerrors.Wrap(
   314  			sdkerrors.ErrInvalidRequest,
   315  			"invalid shares amount",
   316  		)
   317  	}
   318  
   319  	return nil
   320  }
   321  
   322  // NewMsgUndelegate creates a new MsgUndelegate instance.
   323  //
   324  //nolint:interfacer
   325  func NewMsgUndelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Coin) *MsgUndelegate {
   326  	return &MsgUndelegate{
   327  		DelegatorAddress: delAddr.String(),
   328  		ValidatorAddress: valAddr.String(),
   329  		Amount:           amount,
   330  	}
   331  }
   332  
   333  // Route implements the sdk.Msg interface.
   334  func (msg MsgUndelegate) Route() string { return RouterKey }
   335  
   336  // Type implements the sdk.Msg interface.
   337  func (msg MsgUndelegate) Type() string { return TypeMsgUndelegate }
   338  
   339  // GetSigners implements the sdk.Msg interface.
   340  func (msg MsgUndelegate) GetSigners() []sdk.AccAddress {
   341  	delAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddress)
   342  	if err != nil {
   343  		panic(err)
   344  	}
   345  	return []sdk.AccAddress{delAddr}
   346  }
   347  
   348  // GetSignBytes implements the sdk.Msg interface.
   349  func (msg MsgUndelegate) GetSignBytes() []byte {
   350  	bz := ModuleCdc.MustMarshalJSON(&msg)
   351  	return sdk.MustSortJSON(bz)
   352  }
   353  
   354  // ValidateBasic implements the sdk.Msg interface.
   355  func (msg MsgUndelegate) ValidateBasic() error {
   356  	if msg.DelegatorAddress == "" {
   357  		return ErrEmptyDelegatorAddr
   358  	}
   359  
   360  	if msg.ValidatorAddress == "" {
   361  		return ErrEmptyValidatorAddr
   362  	}
   363  
   364  	if !msg.Amount.IsValid() || !msg.Amount.Amount.IsPositive() {
   365  		return sdkerrors.Wrap(
   366  			sdkerrors.ErrInvalidRequest,
   367  			"invalid shares amount",
   368  		)
   369  	}
   370  
   371  	return nil
   372  }