329 lines
9.9 KiB
Go
329 lines
9.9 KiB
Go
package types
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/tendermint/tendermint/crypto"
|
|
)
|
|
|
|
// name to identify transaction types
|
|
const MsgType = "stake"
|
|
|
|
// Verify interface at compile time
|
|
var _, _, _ sdk.Msg = &MsgCreateValidator{}, &MsgEditValidator{}, &MsgDelegate{}
|
|
|
|
//______________________________________________________________________
|
|
|
|
// MsgCreateValidator - struct for bonding transactions
|
|
type MsgCreateValidator struct {
|
|
Description
|
|
Commission CommissionMsg
|
|
DelegatorAddr sdk.AccAddress `json:"delegator_address"`
|
|
ValidatorAddr sdk.ValAddress `json:"validator_address"`
|
|
PubKey crypto.PubKey `json:"pubkey"`
|
|
Delegation sdk.Coin `json:"delegation"`
|
|
}
|
|
|
|
// Default way to create validator. Delegator address and validator address are the same
|
|
func NewMsgCreateValidator(valAddr sdk.ValAddress, pubkey crypto.PubKey,
|
|
selfDelegation sdk.Coin, description Description, commission CommissionMsg) MsgCreateValidator {
|
|
|
|
return NewMsgCreateValidatorOnBehalfOf(
|
|
sdk.AccAddress(valAddr), valAddr, pubkey, selfDelegation, description, commission,
|
|
)
|
|
}
|
|
|
|
// Creates validator msg by delegator address on behalf of validator address
|
|
func NewMsgCreateValidatorOnBehalfOf(delAddr sdk.AccAddress, valAddr sdk.ValAddress,
|
|
pubkey crypto.PubKey, delegation sdk.Coin, description Description, commission CommissionMsg) MsgCreateValidator {
|
|
return MsgCreateValidator{
|
|
Description: description,
|
|
DelegatorAddr: delAddr,
|
|
ValidatorAddr: valAddr,
|
|
PubKey: pubkey,
|
|
Delegation: delegation,
|
|
Commission: commission,
|
|
}
|
|
}
|
|
|
|
//nolint
|
|
func (msg MsgCreateValidator) Type() string { return MsgType }
|
|
func (msg MsgCreateValidator) Name() string { return "create_validator" }
|
|
|
|
// Return address(es) that must sign over msg.GetSignBytes()
|
|
func (msg MsgCreateValidator) GetSigners() []sdk.AccAddress {
|
|
// delegator is first signer so delegator pays fees
|
|
addrs := []sdk.AccAddress{msg.DelegatorAddr}
|
|
|
|
if !bytes.Equal(msg.DelegatorAddr.Bytes(), msg.ValidatorAddr.Bytes()) {
|
|
// if validator addr is not same as delegator addr, validator must sign
|
|
// msg as well
|
|
addrs = append(addrs, sdk.AccAddress(msg.ValidatorAddr))
|
|
}
|
|
return addrs
|
|
}
|
|
|
|
// get the bytes for the message signer to sign on
|
|
func (msg MsgCreateValidator) GetSignBytes() []byte {
|
|
b, err := MsgCdc.MarshalJSON(struct {
|
|
Description
|
|
DelegatorAddr sdk.AccAddress `json:"delegator_address"`
|
|
ValidatorAddr sdk.ValAddress `json:"validator_address"`
|
|
PubKey string `json:"pubkey"`
|
|
Delegation sdk.Coin `json:"delegation"`
|
|
}{
|
|
Description: msg.Description,
|
|
ValidatorAddr: msg.ValidatorAddr,
|
|
PubKey: sdk.MustBech32ifyConsPub(msg.PubKey),
|
|
Delegation: msg.Delegation,
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return sdk.MustSortJSON(b)
|
|
}
|
|
|
|
// quick validity check
|
|
func (msg MsgCreateValidator) ValidateBasic() sdk.Error {
|
|
if msg.DelegatorAddr == nil {
|
|
return ErrNilDelegatorAddr(DefaultCodespace)
|
|
}
|
|
if msg.ValidatorAddr == nil {
|
|
return ErrNilValidatorAddr(DefaultCodespace)
|
|
}
|
|
if !(msg.Delegation.Amount.GT(sdk.ZeroInt())) {
|
|
return ErrBadDelegationAmount(DefaultCodespace)
|
|
}
|
|
if msg.Description == (Description{}) {
|
|
return sdk.NewError(DefaultCodespace, CodeInvalidInput, "description must be included")
|
|
}
|
|
if msg.Commission == (CommissionMsg{}) {
|
|
return sdk.NewError(DefaultCodespace, CodeInvalidInput, "commission must be included")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
//______________________________________________________________________
|
|
|
|
// MsgEditValidator - struct for editing a validator
|
|
type MsgEditValidator struct {
|
|
Description
|
|
ValidatorAddr sdk.ValAddress `json:"address"`
|
|
|
|
// We pass a reference to the new commission rate as it's not mandatory to
|
|
// update. If not updated, the deserialized rate will be zero with no way to
|
|
// distinguish if an update was intended.
|
|
//
|
|
// REF: #2373
|
|
CommissionRate *sdk.Dec `json:"commission_rate"`
|
|
}
|
|
|
|
func NewMsgEditValidator(valAddr sdk.ValAddress, description Description, newRate *sdk.Dec) MsgEditValidator {
|
|
return MsgEditValidator{
|
|
Description: description,
|
|
CommissionRate: newRate,
|
|
ValidatorAddr: valAddr,
|
|
}
|
|
}
|
|
|
|
//nolint
|
|
func (msg MsgEditValidator) Type() string { return MsgType }
|
|
func (msg MsgEditValidator) Name() string { return "edit_validator" }
|
|
func (msg MsgEditValidator) GetSigners() []sdk.AccAddress {
|
|
return []sdk.AccAddress{sdk.AccAddress(msg.ValidatorAddr)}
|
|
}
|
|
|
|
// get the bytes for the message signer to sign on
|
|
func (msg MsgEditValidator) GetSignBytes() []byte {
|
|
b, err := MsgCdc.MarshalJSON(struct {
|
|
Description
|
|
ValidatorAddr sdk.ValAddress `json:"address"`
|
|
}{
|
|
Description: msg.Description,
|
|
ValidatorAddr: msg.ValidatorAddr,
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return sdk.MustSortJSON(b)
|
|
}
|
|
|
|
// quick validity check
|
|
func (msg MsgEditValidator) ValidateBasic() sdk.Error {
|
|
if msg.ValidatorAddr == nil {
|
|
return sdk.NewError(DefaultCodespace, CodeInvalidInput, "nil validator address")
|
|
}
|
|
|
|
if msg.Description == (Description{}) {
|
|
return sdk.NewError(DefaultCodespace, CodeInvalidInput, "transaction must include some information to modify")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
//______________________________________________________________________
|
|
|
|
// MsgDelegate - struct for bonding transactions
|
|
type MsgDelegate struct {
|
|
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
|
|
ValidatorAddr sdk.ValAddress `json:"validator_addr"`
|
|
Delegation sdk.Coin `json:"delegation"`
|
|
}
|
|
|
|
func NewMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, delegation sdk.Coin) MsgDelegate {
|
|
return MsgDelegate{
|
|
DelegatorAddr: delAddr,
|
|
ValidatorAddr: valAddr,
|
|
Delegation: delegation,
|
|
}
|
|
}
|
|
|
|
//nolint
|
|
func (msg MsgDelegate) Type() string { return MsgType }
|
|
func (msg MsgDelegate) Name() string { return "delegate" }
|
|
func (msg MsgDelegate) GetSigners() []sdk.AccAddress {
|
|
return []sdk.AccAddress{msg.DelegatorAddr}
|
|
}
|
|
|
|
// get the bytes for the message signer to sign on
|
|
func (msg MsgDelegate) GetSignBytes() []byte {
|
|
b, err := MsgCdc.MarshalJSON(msg)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return sdk.MustSortJSON(b)
|
|
}
|
|
|
|
// quick validity check
|
|
func (msg MsgDelegate) ValidateBasic() sdk.Error {
|
|
if msg.DelegatorAddr == nil {
|
|
return ErrNilDelegatorAddr(DefaultCodespace)
|
|
}
|
|
if msg.ValidatorAddr == nil {
|
|
return ErrNilValidatorAddr(DefaultCodespace)
|
|
}
|
|
if !(msg.Delegation.Amount.GT(sdk.ZeroInt())) {
|
|
return ErrBadDelegationAmount(DefaultCodespace)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
//______________________________________________________________________
|
|
|
|
// MsgDelegate - struct for bonding transactions
|
|
type MsgBeginRedelegate struct {
|
|
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
|
|
ValidatorSrcAddr sdk.ValAddress `json:"validator_src_addr"`
|
|
ValidatorDstAddr sdk.ValAddress `json:"validator_dst_addr"`
|
|
SharesAmount sdk.Dec `json:"shares_amount"`
|
|
}
|
|
|
|
func NewMsgBeginRedelegate(delAddr sdk.AccAddress, valSrcAddr,
|
|
valDstAddr sdk.ValAddress, sharesAmount sdk.Dec) MsgBeginRedelegate {
|
|
|
|
return MsgBeginRedelegate{
|
|
DelegatorAddr: delAddr,
|
|
ValidatorSrcAddr: valSrcAddr,
|
|
ValidatorDstAddr: valDstAddr,
|
|
SharesAmount: sharesAmount,
|
|
}
|
|
}
|
|
|
|
//nolint
|
|
func (msg MsgBeginRedelegate) Type() string { return MsgType }
|
|
func (msg MsgBeginRedelegate) Name() string { return "begin_redelegate" }
|
|
func (msg MsgBeginRedelegate) GetSigners() []sdk.AccAddress {
|
|
return []sdk.AccAddress{msg.DelegatorAddr}
|
|
}
|
|
|
|
// get the bytes for the message signer to sign on
|
|
func (msg MsgBeginRedelegate) GetSignBytes() []byte {
|
|
b, err := MsgCdc.MarshalJSON(struct {
|
|
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
|
|
ValidatorSrcAddr sdk.ValAddress `json:"validator_src_addr"`
|
|
ValidatorDstAddr sdk.ValAddress `json:"validator_dst_addr"`
|
|
SharesAmount string `json:"shares"`
|
|
}{
|
|
DelegatorAddr: msg.DelegatorAddr,
|
|
ValidatorSrcAddr: msg.ValidatorSrcAddr,
|
|
ValidatorDstAddr: msg.ValidatorDstAddr,
|
|
SharesAmount: msg.SharesAmount.String(),
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return sdk.MustSortJSON(b)
|
|
}
|
|
|
|
// quick validity check
|
|
func (msg MsgBeginRedelegate) ValidateBasic() sdk.Error {
|
|
if msg.DelegatorAddr == nil {
|
|
return ErrNilDelegatorAddr(DefaultCodespace)
|
|
}
|
|
if msg.ValidatorSrcAddr == nil {
|
|
return ErrNilValidatorAddr(DefaultCodespace)
|
|
}
|
|
if msg.ValidatorDstAddr == nil {
|
|
return ErrNilValidatorAddr(DefaultCodespace)
|
|
}
|
|
if msg.SharesAmount.LTE(sdk.ZeroDec()) {
|
|
return ErrBadSharesAmount(DefaultCodespace)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
//______________________________________________________________________
|
|
|
|
// MsgBeginUnbonding - struct for unbonding transactions
|
|
type MsgBeginUnbonding struct {
|
|
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
|
|
ValidatorAddr sdk.ValAddress `json:"validator_addr"`
|
|
SharesAmount sdk.Dec `json:"shares_amount"`
|
|
}
|
|
|
|
func NewMsgBeginUnbonding(delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec) MsgBeginUnbonding {
|
|
return MsgBeginUnbonding{
|
|
DelegatorAddr: delAddr,
|
|
ValidatorAddr: valAddr,
|
|
SharesAmount: sharesAmount,
|
|
}
|
|
}
|
|
|
|
//nolint
|
|
func (msg MsgBeginUnbonding) Type() string { return MsgType }
|
|
func (msg MsgBeginUnbonding) Name() string { return "begin_unbonding" }
|
|
func (msg MsgBeginUnbonding) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.DelegatorAddr} }
|
|
|
|
// get the bytes for the message signer to sign on
|
|
func (msg MsgBeginUnbonding) GetSignBytes() []byte {
|
|
b, err := MsgCdc.MarshalJSON(struct {
|
|
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
|
|
ValidatorAddr sdk.ValAddress `json:"validator_addr"`
|
|
SharesAmount string `json:"shares_amount"`
|
|
}{
|
|
DelegatorAddr: msg.DelegatorAddr,
|
|
ValidatorAddr: msg.ValidatorAddr,
|
|
SharesAmount: msg.SharesAmount.String(),
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return sdk.MustSortJSON(b)
|
|
}
|
|
|
|
// quick validity check
|
|
func (msg MsgBeginUnbonding) ValidateBasic() sdk.Error {
|
|
if msg.DelegatorAddr == nil {
|
|
return ErrNilDelegatorAddr(DefaultCodespace)
|
|
}
|
|
if msg.ValidatorAddr == nil {
|
|
return ErrNilValidatorAddr(DefaultCodespace)
|
|
}
|
|
if msg.SharesAmount.LTE(sdk.ZeroDec()) {
|
|
return ErrBadSharesAmount(DefaultCodespace)
|
|
}
|
|
return nil
|
|
}
|