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 }