2018-06-26 19:00:12 -07:00
package types
2018-01-25 19:31:07 -08:00
import (
2018-04-30 23:07:06 -07:00
"bytes"
2018-05-26 14:21:29 -07:00
"fmt"
2019-12-18 05:20:02 -08:00
"sort"
2019-01-22 09:28:39 -08:00
"strings"
2018-08-24 18:47:31 -07:00
"time"
2018-04-30 23:07:06 -07:00
2018-06-28 17:54:47 -07:00
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
2020-08-28 09:02:38 -07:00
"github.com/tendermint/tendermint/crypto/encoding"
2018-06-04 16:42:01 -07:00
tmtypes "github.com/tendermint/tendermint/types"
2020-08-28 09:02:38 -07:00
"gopkg.in/yaml.v2"
2018-06-26 19:00:12 -07:00
2018-09-13 11:17:32 -07:00
"github.com/cosmos/cosmos-sdk/codec"
2020-10-23 05:07:52 -07:00
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
2020-09-25 01:41:16 -07:00
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
2018-06-26 19:00:12 -07:00
sdk "github.com/cosmos/cosmos-sdk/types"
2019-12-27 09:57:54 -08:00
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
2018-01-25 19:31:07 -08:00
)
2019-02-07 17:41:23 -08:00
const (
// TODO: Why can't we just have one string description which can be JSON by convention
2019-08-12 06:10:16 -07:00
MaxMonikerLength = 70
MaxIdentityLength = 3000
MaxWebsiteLength = 140
MaxSecurityContactLength = 140
MaxDetailsLength = 280
2019-02-07 17:41:23 -08:00
)
2020-10-12 06:56:02 -07:00
var (
BondStatusUnspecified = BondStatus_name [ int32 ( Unspecified ) ]
BondStatusUnbonded = BondStatus_name [ int32 ( Unbonded ) ]
BondStatusUnbonding = BondStatus_name [ int32 ( Unbonding ) ]
BondStatusBonded = BondStatus_name [ int32 ( Bonded ) ]
)
var _ ValidatorI = Validator { }
2019-06-04 15:06:58 -07:00
2020-09-25 03:25:37 -07:00
// NewValidator constructs a new Validator
//nolint:interfacer
2020-10-23 05:07:52 -07:00
func NewValidator ( operator sdk . ValAddress , pubKey crypto . PubKey , description Description ) ( Validator , error ) {
pkAny , err := codectypes . PackAny ( pubKey )
if err != nil {
return Validator { } , err
2020-02-06 11:21:02 -08:00
}
return Validator {
2020-09-25 03:25:37 -07:00
OperatorAddress : operator . String ( ) ,
2020-10-23 05:07:52 -07:00
ConsensusPubkey : pkAny ,
2020-02-06 11:21:02 -08:00
Jailed : false ,
2020-10-12 06:56:02 -07:00
Status : Unbonded ,
2020-02-06 11:21:02 -08:00
Tokens : sdk . ZeroInt ( ) ,
DelegatorShares : sdk . ZeroDec ( ) ,
Description : description ,
UnbondingHeight : int64 ( 0 ) ,
UnbondingTime : time . Unix ( 0 , 0 ) . UTC ( ) ,
Commission : NewCommission ( sdk . ZeroDec ( ) , sdk . ZeroDec ( ) , sdk . ZeroDec ( ) ) ,
MinSelfDelegation : sdk . OneInt ( ) ,
2020-10-23 05:07:52 -07:00
} , nil
2020-02-06 11:21:02 -08:00
}
2019-06-08 11:00:36 -07:00
2020-02-06 11:21:02 -08:00
// String implements the Stringer interface for a Validator object.
func ( v Validator ) String ( ) string {
out , _ := yaml . Marshal ( v )
return string ( out )
2019-06-08 11:00:36 -07:00
}
2019-01-22 09:28:39 -08:00
// Validators is a collection of Validator
type Validators [ ] Validator
func ( v Validators ) String ( ) ( out string ) {
for _ , val := range v {
out += val . String ( ) + "\n"
}
2020-05-02 12:26:59 -07:00
2019-01-22 09:28:39 -08:00
return strings . TrimSpace ( out )
}
2019-02-13 15:01:50 -08:00
// ToSDKValidators - convenience function convert []Validators to []sdk.Validators
2020-10-12 06:56:02 -07:00
func ( v Validators ) ToSDKValidators ( ) ( validators [ ] ValidatorI ) {
2019-02-13 15:01:50 -08:00
for _ , val := range v {
validators = append ( validators , val )
}
2020-05-02 12:26:59 -07:00
2019-02-13 15:01:50 -08:00
return validators
}
2020-01-29 05:35:49 -08:00
// ToTmValidators casts all validators to the corresponding tendermint type.
2020-10-23 05:07:52 -07:00
func ( v Validators ) ToTmValidators ( ) ( [ ] * tmtypes . Validator , error ) {
2020-01-29 05:35:49 -08:00
validators := make ( [ ] * tmtypes . Validator , len ( v ) )
2020-10-23 05:07:52 -07:00
var err error
2020-01-29 05:35:49 -08:00
for i , val := range v {
2020-10-23 05:07:52 -07:00
validators [ i ] , err = val . ToTmValidator ( )
if err != nil {
return nil , err
}
2020-01-29 05:35:49 -08:00
}
2020-05-02 12:26:59 -07:00
2020-10-23 05:07:52 -07:00
return validators , nil
2020-01-29 05:35:49 -08:00
}
2019-12-18 05:20:02 -08:00
// Sort Validators sorts validator array in ascending operator address order
func ( v Validators ) Sort ( ) {
sort . Sort ( v )
}
// Implements sort interface
func ( v Validators ) Len ( ) int {
return len ( v )
}
// Implements sort interface
func ( v Validators ) Less ( i , j int ) bool {
2020-09-25 03:25:37 -07:00
return bytes . Compare ( v [ i ] . GetOperator ( ) . Bytes ( ) , v [ j ] . GetOperator ( ) . Bytes ( ) ) == - 1
2019-12-18 05:20:02 -08:00
}
// Implements sort interface
func ( v Validators ) Swap ( i , j int ) {
it := v [ i ]
v [ i ] = v [ j ]
v [ j ] = it
}
2020-10-23 05:07:52 -07:00
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func ( v Validators ) UnpackInterfaces ( c codectypes . AnyUnpacker ) error {
for i := range v {
if err := v [ i ] . UnpackInterfaces ( c ) ; err != nil {
return err
}
}
return nil
}
2019-01-07 12:42:52 -08:00
// return the redelegation
2020-10-23 05:07:52 -07:00
func MustMarshalValidator ( cdc codec . BinaryMarshaler , validator * Validator ) [ ] byte {
return cdc . MustMarshalBinaryBare ( validator )
2018-07-03 22:32:49 -07:00
}
2019-01-07 12:42:52 -08:00
// unmarshal a redelegation from a store value
2020-07-25 01:03:58 -07:00
func MustUnmarshalValidator ( cdc codec . BinaryMarshaler , value [ ] byte ) Validator {
2019-01-07 12:42:52 -08:00
validator , err := UnmarshalValidator ( cdc , value )
2018-07-04 14:07:06 -07:00
if err != nil {
panic ( err )
}
2020-05-02 12:26:59 -07:00
2018-07-04 14:07:06 -07:00
return validator
}
2019-01-07 12:42:52 -08:00
// unmarshal a redelegation from a store value
2020-07-25 01:03:58 -07:00
func UnmarshalValidator ( cdc codec . BinaryMarshaler , value [ ] byte ) ( v Validator , err error ) {
2020-03-13 12:58:43 -07:00
err = cdc . UnmarshalBinaryBare ( value , & v )
2020-02-06 11:21:02 -08:00
return v , err
2018-08-31 17:01:23 -07:00
}
2019-06-04 15:06:58 -07:00
// IsBonded checks if the validator status equals Bonded
func ( v Validator ) IsBonded ( ) bool {
2020-10-12 06:56:02 -07:00
return v . GetStatus ( ) == Bonded
2019-06-04 15:06:58 -07:00
}
// IsUnbonded checks if the validator status equals Unbonded
func ( v Validator ) IsUnbonded ( ) bool {
2020-10-12 06:56:02 -07:00
return v . GetStatus ( ) == Unbonded
2019-06-04 15:06:58 -07:00
}
// IsUnbonding checks if the validator status equals Unbonding
func ( v Validator ) IsUnbonding ( ) bool {
2020-10-12 06:56:02 -07:00
return v . GetStatus ( ) == Unbonding
2019-06-04 15:06:58 -07:00
}
2018-07-26 10:41:34 -07:00
// constant used in flags to indicate that description field should not be updated
const DoNotModifyDesc = "[do-not-modify]"
2019-08-12 06:10:16 -07:00
func NewDescription ( moniker , identity , website , securityContact , details string ) Description {
2018-03-26 07:48:15 -07:00
return Description {
2019-08-12 06:10:16 -07:00
Moniker : moniker ,
Identity : identity ,
Website : website ,
SecurityContact : securityContact ,
Details : details ,
2018-03-26 07:48:15 -07:00
}
}
2020-02-06 11:21:02 -08:00
// String implements the Stringer interface for a Description object.
func ( d Description ) String ( ) string {
out , _ := yaml . Marshal ( d )
return string ( out )
}
2018-07-03 21:21:36 -07:00
// UpdateDescription updates the fields of a given description. An error is
// returned if the resulting description contains an invalid length.
2019-12-27 09:57:54 -08:00
func ( d Description ) UpdateDescription ( d2 Description ) ( Description , error ) {
2018-07-26 10:41:34 -07:00
if d2 . Moniker == DoNotModifyDesc {
2018-06-26 19:00:12 -07:00
d2 . Moniker = d . Moniker
}
2020-05-02 12:26:59 -07:00
2018-07-26 10:41:34 -07:00
if d2 . Identity == DoNotModifyDesc {
2018-06-26 19:00:12 -07:00
d2 . Identity = d . Identity
}
2020-05-02 12:26:59 -07:00
2018-07-26 10:41:34 -07:00
if d2 . Website == DoNotModifyDesc {
2018-06-26 19:00:12 -07:00
d2 . Website = d . Website
}
2020-05-02 12:26:59 -07:00
2019-08-12 06:10:16 -07:00
if d2 . SecurityContact == DoNotModifyDesc {
d2 . SecurityContact = d . SecurityContact
}
2020-05-02 12:26:59 -07:00
2018-07-26 10:41:34 -07:00
if d2 . Details == DoNotModifyDesc {
2018-06-26 19:00:12 -07:00
d2 . Details = d . Details
}
2018-07-03 21:21:36 -07:00
2019-08-12 06:10:16 -07:00
return NewDescription (
d2 . Moniker ,
d2 . Identity ,
d2 . Website ,
d2 . SecurityContact ,
d2 . Details ,
) . EnsureLength ( )
2018-06-26 19:00:12 -07:00
}
2018-07-03 21:21:36 -07:00
// EnsureLength ensures the length of a validator's description.
2019-12-27 09:57:54 -08:00
func ( d Description ) EnsureLength ( ) ( Description , error ) {
2019-02-07 17:41:23 -08:00
if len ( d . Moniker ) > MaxMonikerLength {
2019-12-27 09:57:54 -08:00
return d , sdkerrors . Wrapf ( sdkerrors . ErrInvalidRequest , "invalid moniker length; got: %d, max: %d" , len ( d . Moniker ) , MaxMonikerLength )
2018-06-26 19:00:12 -07:00
}
2020-05-02 12:26:59 -07:00
2019-02-07 17:41:23 -08:00
if len ( d . Identity ) > MaxIdentityLength {
2019-12-27 09:57:54 -08:00
return d , sdkerrors . Wrapf ( sdkerrors . ErrInvalidRequest , "invalid identity length; got: %d, max: %d" , len ( d . Identity ) , MaxIdentityLength )
2018-06-26 19:00:12 -07:00
}
2020-05-02 12:26:59 -07:00
2019-02-07 17:41:23 -08:00
if len ( d . Website ) > MaxWebsiteLength {
2019-12-27 09:57:54 -08:00
return d , sdkerrors . Wrapf ( sdkerrors . ErrInvalidRequest , "invalid website length; got: %d, max: %d" , len ( d . Website ) , MaxWebsiteLength )
2018-06-26 19:00:12 -07:00
}
2020-05-02 12:26:59 -07:00
2019-08-12 06:10:16 -07:00
if len ( d . SecurityContact ) > MaxSecurityContactLength {
2019-12-27 09:57:54 -08:00
return d , sdkerrors . Wrapf ( sdkerrors . ErrInvalidRequest , "invalid security contact length; got: %d, max: %d" , len ( d . SecurityContact ) , MaxSecurityContactLength )
2019-08-12 06:10:16 -07:00
}
2020-05-02 12:26:59 -07:00
2019-02-07 17:41:23 -08:00
if len ( d . Details ) > MaxDetailsLength {
2019-12-27 09:57:54 -08:00
return d , sdkerrors . Wrapf ( sdkerrors . ErrInvalidRequest , "invalid details length; got: %d, max: %d" , len ( d . Details ) , MaxDetailsLength )
2018-06-26 19:00:12 -07:00
}
2018-07-03 21:21:36 -07:00
2018-06-26 19:00:12 -07:00
return d , nil
}
2018-05-12 15:54:50 -07:00
2019-02-07 17:41:23 -08:00
// ABCIValidatorUpdate returns an abci.ValidatorUpdate from a staking validator type
2018-10-03 08:48:23 -07:00
// with the full validator power
func ( v Validator ) ABCIValidatorUpdate ( ) abci . ValidatorUpdate {
2020-10-23 05:07:52 -07:00
consPk , err := v . TmConsPubKey ( )
if err != nil {
panic ( err )
}
pk , err := encoding . PubKeyToProto ( consPk )
2020-08-14 10:58:53 -07:00
if err != nil {
panic ( err )
}
2018-10-03 08:48:23 -07:00
return abci . ValidatorUpdate {
2020-08-14 10:58:53 -07:00
PubKey : pk ,
2019-06-12 08:57:47 -07:00
Power : v . ConsensusPower ( ) ,
2018-04-04 20:22:13 -07:00
}
2018-01-31 18:56:46 -08:00
}
2019-02-07 17:41:23 -08:00
// ABCIValidatorUpdateZero returns an abci.ValidatorUpdate from a staking validator type
2018-10-03 08:48:23 -07:00
// with zero power used for validator updates.
func ( v Validator ) ABCIValidatorUpdateZero ( ) abci . ValidatorUpdate {
2020-10-23 05:07:52 -07:00
consPk , err := v . TmConsPubKey ( )
if err != nil {
panic ( err )
}
pk , err := encoding . PubKeyToProto ( consPk )
2020-08-14 10:58:53 -07:00
if err != nil {
panic ( err )
}
2018-10-03 08:48:23 -07:00
return abci . ValidatorUpdate {
2020-08-14 10:58:53 -07:00
PubKey : pk ,
2018-10-03 08:48:23 -07:00
Power : 0 ,
2018-04-05 09:31:36 -07:00
}
}
2020-01-29 05:35:49 -08:00
// ToTmValidator casts an SDK validator to a tendermint type Validator.
2020-10-23 05:07:52 -07:00
func ( v Validator ) ToTmValidator ( ) ( * tmtypes . Validator , error ) {
consPk , err := v . TmConsPubKey ( )
if err != nil {
return nil , err
}
return tmtypes . NewValidator ( consPk , v . ConsensusPower ( ) ) , nil
2020-01-29 05:35:49 -08:00
}
2018-09-24 15:23:58 -07:00
// SetInitialCommission attempts to set a validator's initial commission. An
// error is returned if the commission is invalid.
2019-12-27 09:57:54 -08:00
func ( v Validator ) SetInitialCommission ( commission Commission ) ( Validator , error ) {
2018-09-24 15:23:58 -07:00
if err := commission . Validate ( ) ; err != nil {
return v , err
}
v . Commission = commission
2020-05-02 12:26:59 -07:00
2018-09-24 15:23:58 -07:00
return v , nil
}
2019-03-06 10:54:12 -08:00
// In some situations, the exchange rate becomes invalid, e.g. if
// Validator loses all tokens due to slashing. In this case,
// make all future delegations invalid.
func ( v Validator ) InvalidExRate ( ) bool {
return v . Tokens . IsZero ( ) && v . DelegatorShares . IsPositive ( )
}
// calculate the token worth of provided shares
2019-03-25 14:13:02 -07:00
func ( v Validator ) TokensFromShares ( shares sdk . Dec ) sdk . Dec {
2019-03-06 10:54:12 -08:00
return ( shares . MulInt ( v . Tokens ) ) . Quo ( v . DelegatorShares )
}
// calculate the token worth of provided shares, truncated
2019-03-25 14:13:02 -07:00
func ( v Validator ) TokensFromSharesTruncated ( shares sdk . Dec ) sdk . Dec {
2019-03-06 10:54:12 -08:00
return ( shares . MulInt ( v . Tokens ) ) . QuoTruncate ( v . DelegatorShares )
2018-07-13 13:46:14 -07:00
}
2018-07-03 21:21:36 -07:00
2019-04-10 15:53:42 -07:00
// TokensFromSharesRoundUp returns the token worth of provided shares, rounded
// up.
func ( v Validator ) TokensFromSharesRoundUp ( shares sdk . Dec ) sdk . Dec {
return ( shares . MulInt ( v . Tokens ) ) . QuoRoundUp ( v . DelegatorShares )
}
2019-03-25 14:13:02 -07:00
// SharesFromTokens returns the shares of a delegation given a bond amount. It
// returns an error if the validator has no tokens.
2019-12-27 09:57:54 -08:00
func ( v Validator ) SharesFromTokens ( amt sdk . Int ) ( sdk . Dec , error ) {
2019-03-25 14:13:02 -07:00
if v . Tokens . IsZero ( ) {
2019-12-27 09:57:54 -08:00
return sdk . ZeroDec ( ) , ErrInsufficientShares
2019-03-25 14:13:02 -07:00
}
return v . GetDelegatorShares ( ) . MulInt ( amt ) . QuoInt ( v . GetTokens ( ) ) , nil
}
// SharesFromTokensTruncated returns the truncated shares of a delegation given
// a bond amount. It returns an error if the validator has no tokens.
2019-12-27 09:57:54 -08:00
func ( v Validator ) SharesFromTokensTruncated ( amt sdk . Int ) ( sdk . Dec , error ) {
2019-03-25 14:13:02 -07:00
if v . Tokens . IsZero ( ) {
2019-12-27 09:57:54 -08:00
return sdk . ZeroDec ( ) , ErrInsufficientShares
2019-03-25 14:13:02 -07:00
}
return v . GetDelegatorShares ( ) . MulInt ( amt ) . QuoTruncate ( v . GetTokens ( ) . ToDec ( ) ) , nil
}
2019-02-05 21:30:48 -08:00
// get the bonded tokens which the validator holds
2019-01-02 12:29:47 -08:00
func ( v Validator ) BondedTokens ( ) sdk . Int {
2019-06-04 15:06:58 -07:00
if v . IsBonded ( ) {
2018-07-13 13:46:14 -07:00
return v . Tokens
}
2020-05-02 12:26:59 -07:00
2019-01-02 12:29:47 -08:00
return sdk . ZeroInt ( )
2018-05-15 21:41:21 -07:00
}
2019-06-12 08:57:47 -07:00
// get the consensus-engine power
2019-02-15 07:55:21 -08:00
// a reduction of 10^6 from validator tokens is applied
2019-06-12 08:57:47 -07:00
func ( v Validator ) ConsensusPower ( ) int64 {
2019-06-04 15:06:58 -07:00
if v . IsBonded ( ) {
2019-06-12 08:57:47 -07:00
return v . PotentialConsensusPower ( )
2019-02-05 21:30:48 -08:00
}
2020-05-02 12:26:59 -07:00
2019-02-05 21:30:48 -08:00
return 0
}
2019-06-12 08:57:47 -07:00
// potential consensus-engine power
func ( v Validator ) PotentialConsensusPower ( ) int64 {
return sdk . TokensToConsensusPower ( v . Tokens )
2019-02-05 21:30:48 -08:00
}
2019-06-28 13:11:27 -07:00
// UpdateStatus updates the location of the shares within a validator
// to reflect the new status
2020-10-12 06:56:02 -07:00
func ( v Validator ) UpdateStatus ( newStatus BondStatus ) Validator {
2019-06-28 13:11:27 -07:00
v . Status = newStatus
return v
}
// AddTokensFromDel adds tokens to a validator
func ( v Validator ) AddTokensFromDel ( amount sdk . Int ) ( Validator , sdk . Dec ) {
// calculate the shares to issue
var issuedShares sdk . Dec
if v . DelegatorShares . IsZero ( ) {
// the first delegation to a validator sets the exchange rate to one
issuedShares = amount . ToDec ( )
} else {
shares , err := v . SharesFromTokens ( amount )
if err != nil {
panic ( err )
}
issuedShares = shares
}
v . Tokens = v . Tokens . Add ( amount )
v . DelegatorShares = v . DelegatorShares . Add ( issuedShares )
return v , issuedShares
}
// RemoveTokens removes tokens from a validator
func ( v Validator ) RemoveTokens ( tokens sdk . Int ) Validator {
if tokens . IsNegative ( ) {
panic ( fmt . Sprintf ( "should not happen: trying to remove negative tokens %v" , tokens ) )
}
2020-05-02 12:26:59 -07:00
2019-06-28 13:11:27 -07:00
if v . Tokens . LT ( tokens ) {
panic ( fmt . Sprintf ( "should not happen: only have %v tokens, trying to remove %v" , v . Tokens , tokens ) )
}
2020-05-02 12:26:59 -07:00
2019-06-28 13:11:27 -07:00
v . Tokens = v . Tokens . Sub ( tokens )
2020-05-02 12:26:59 -07:00
2019-06-28 13:11:27 -07:00
return v
}
// RemoveDelShares removes delegator shares from a validator.
// NOTE: because token fractions are left in the valiadator,
// the exchange rate of future shares of this validator can increase.
func ( v Validator ) RemoveDelShares ( delShares sdk . Dec ) ( Validator , sdk . Int ) {
remainingShares := v . DelegatorShares . Sub ( delShares )
2020-02-06 11:21:02 -08:00
2019-06-28 13:11:27 -07:00
var issuedTokens sdk . Int
if remainingShares . IsZero ( ) {
// last delegation share gets any trimmings
issuedTokens = v . Tokens
v . Tokens = sdk . ZeroInt ( )
} else {
// leave excess tokens in the validator
// however fully use all the delegator shares
issuedTokens = v . TokensFromShares ( delShares ) . TruncateInt ( )
v . Tokens = v . Tokens . Sub ( issuedTokens )
2020-02-06 11:21:02 -08:00
2019-06-28 13:11:27 -07:00
if v . Tokens . IsNegative ( ) {
panic ( "attempting to remove more tokens than available in validator" )
}
}
v . DelegatorShares = remainingShares
2020-05-02 12:26:59 -07:00
2019-06-28 13:11:27 -07:00
return v , issuedTokens
}
2020-02-06 11:21:02 -08:00
// MinEqual defines a more minimum set of equality conditions when comparing two
// validators.
2020-10-23 05:07:52 -07:00
func ( v * Validator ) MinEqual ( other * Validator ) bool {
return v . OperatorAddress == other . OperatorAddress &&
2020-10-12 06:56:02 -07:00
v . Status == other . Status &&
2020-02-06 11:21:02 -08:00
v . Tokens . Equal ( other . Tokens ) &&
v . DelegatorShares . Equal ( other . DelegatorShares ) &&
2020-10-23 05:07:52 -07:00
v . Description . Equal ( other . Description ) &&
v . Commission . Equal ( other . Commission ) &&
v . Jailed == other . Jailed &&
v . MinSelfDelegation . Equal ( other . MinSelfDelegation ) &&
v . ConsensusPubkey . Equal ( other . ConsensusPubkey )
}
// Equal checks if the receiver equals the parameter
func ( v * Validator ) Equal ( v2 * Validator ) bool {
return v . MinEqual ( v2 ) &&
v . UnbondingHeight == v2 . UnbondingHeight &&
v . UnbondingTime . Equal ( v2 . UnbondingTime )
2020-02-06 11:21:02 -08:00
}
2020-10-12 06:56:02 -07:00
func ( v Validator ) IsJailed ( ) bool { return v . Jailed }
func ( v Validator ) GetMoniker ( ) string { return v . Description . Moniker }
func ( v Validator ) GetStatus ( ) BondStatus { return v . Status }
2020-09-25 03:25:37 -07:00
func ( v Validator ) GetOperator ( ) sdk . ValAddress {
if v . OperatorAddress == "" {
return nil
}
addr , err := sdk . ValAddressFromBech32 ( v . OperatorAddress )
if err != nil {
panic ( err )
}
return addr
}
2020-10-23 05:07:52 -07:00
// TmConsPubKey casts Validator.ConsensusPubkey to crypto.PubKey
func ( v Validator ) TmConsPubKey ( ) ( crypto . PubKey , error ) {
pk , ok := v . ConsensusPubkey . GetCachedValue ( ) . ( cryptotypes . PubKey )
if ! ok {
return nil , sdkerrors . Wrapf ( sdkerrors . ErrInvalidType , "Expecting crypto.PubKey, got %T" , pk )
}
2020-09-25 01:41:16 -07:00
// The way things are refactored now, v.ConsensusPubkey is sometimes a TM
// ed25519 pubkey, sometimes our own ed25519 pubkey. This is very ugly and
// inconsistent.
// Luckily, here we coerce it into a TM ed25519 pubkey always, as this
// pubkey will be passed into TM (eg calling encoding.PubKeyToProto).
if intoTmPk , ok := pk . ( cryptotypes . IntoTmPubKey ) ; ok {
2020-10-23 05:07:52 -07:00
return intoTmPk . AsTmPubKey ( ) , nil
2020-09-25 01:41:16 -07:00
}
2020-10-23 05:07:52 -07:00
return nil , sdkerrors . Wrapf ( sdkerrors . ErrInvalidPubKey , "Logic error: ConsensusPubkey must be an SDK key and SDK PubKey types must be convertible to tendermint PubKey; got: %T" , pk )
}
2020-09-25 01:41:16 -07:00
2020-10-23 05:07:52 -07:00
// GetConsAddr extracts Consensus key address
func ( v Validator ) GetConsAddr ( ) ( sdk . ConsAddress , error ) {
pk , err := v . TmConsPubKey ( )
if err != nil {
return sdk . ConsAddress { } , err
}
return sdk . ConsAddress ( pk . Address ( ) ) , nil
2020-02-06 11:21:02 -08:00
}
2020-10-23 05:07:52 -07:00
2019-03-06 10:54:12 -08:00
func ( v Validator ) GetTokens ( ) sdk . Int { return v . Tokens }
func ( v Validator ) GetBondedTokens ( ) sdk . Int { return v . BondedTokens ( ) }
2019-06-12 08:57:47 -07:00
func ( v Validator ) GetConsensusPower ( ) int64 { return v . ConsensusPower ( ) }
2019-03-06 10:54:12 -08:00
func ( v Validator ) GetCommission ( ) sdk . Dec { return v . Commission . Rate }
func ( v Validator ) GetMinSelfDelegation ( ) sdk . Int { return v . MinSelfDelegation }
func ( v Validator ) GetDelegatorShares ( ) sdk . Dec { return v . DelegatorShares }
2020-10-23 05:07:52 -07:00
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func ( v Validator ) UnpackInterfaces ( unpacker codectypes . AnyUnpacker ) error {
var pk crypto . PubKey
return unpacker . UnpackAny ( v . ConsensusPubkey , & pk )
}