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-07-04 14:07:06 -07:00
|
|
|
"errors"
|
2018-05-26 14:21:29 -07:00
|
|
|
"fmt"
|
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"
|
2018-06-04 16:42:01 -07:00
|
|
|
tmtypes "github.com/tendermint/tendermint/types"
|
2018-06-26 19:00:12 -07:00
|
|
|
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2018-07-03 22:32:49 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/wire"
|
2018-01-25 19:31:07 -08:00
|
|
|
)
|
|
|
|
|
2018-07-03 21:21:36 -07:00
|
|
|
const doNotModifyDescVal = "[do-not-modify]"
|
|
|
|
|
2018-05-09 21:01:58 -07:00
|
|
|
// Validator defines the total amount of bond shares and their exchange rate to
|
2018-01-25 19:31:07 -08:00
|
|
|
// coins. Accumulation of interest is modelled as an in increase in the
|
|
|
|
// exchange rate, and slashing as a decrease. When coins are delegated to this
|
2018-05-09 21:01:58 -07:00
|
|
|
// validator, the validator is credited with a Delegation whose number of
|
2018-01-25 19:31:07 -08:00
|
|
|
// bond shares is based on the amount of coins delegated divided by the current
|
|
|
|
// exchange rate. Voting power can be calculated as total bonds multiplied by
|
|
|
|
// exchange rate.
|
2018-05-09 21:01:58 -07:00
|
|
|
type Validator struct {
|
2018-07-06 00:06:53 -07:00
|
|
|
Owner sdk.AccAddress `json:"owner"` // sender of BondTx - UnbondTx returns here
|
|
|
|
PubKey crypto.PubKey `json:"pub_key"` // pubkey of validator
|
|
|
|
Revoked bool `json:"revoked"` // has the validator been revoked from bonded status?
|
2018-05-11 14:58:28 -07:00
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded)
|
|
|
|
Tokens sdk.Rat `json:"tokens"` // delegated tokens (incl. self-delegation)
|
|
|
|
DelegatorShares sdk.Rat `json:"delegator_shares"` // total shares issued to a validator's delegators
|
2018-05-11 14:58:28 -07:00
|
|
|
|
2018-05-18 15:57:47 -07:00
|
|
|
Description Description `json:"description"` // description terms for the validator
|
|
|
|
BondHeight int64 `json:"bond_height"` // earliest height as a bonded validator
|
|
|
|
BondIntraTxCounter int16 `json:"bond_intra_tx_counter"` // block-local tx index of validator change
|
|
|
|
ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer
|
2018-05-04 12:38:25 -07:00
|
|
|
|
|
|
|
Commission sdk.Rat `json:"commission"` // XXX the commission rate of fees charged to any delegators
|
2018-05-09 21:01:58 -07:00
|
|
|
CommissionMax sdk.Rat `json:"commission_max"` // XXX maximum commission rate which this validator can ever charge
|
|
|
|
CommissionChangeRate sdk.Rat `json:"commission_change_rate"` // XXX maximum daily increase of the validator commission
|
2018-05-04 12:38:25 -07:00
|
|
|
CommissionChangeToday sdk.Rat `json:"commission_change_today"` // XXX commission rate change today, reset each day (UTC time)
|
|
|
|
|
|
|
|
// fee related
|
2018-07-13 13:46:14 -07:00
|
|
|
LastBondedTokens sdk.Rat `json:"prev_bonded_tokens"` // Previous bonded tokens held
|
2018-01-25 19:31:07 -08:00
|
|
|
}
|
|
|
|
|
2018-05-09 21:01:58 -07:00
|
|
|
// NewValidator - initialize a new validator
|
2018-07-06 00:06:53 -07:00
|
|
|
func NewValidator(owner sdk.AccAddress, pubKey crypto.PubKey, description Description) Validator {
|
2018-05-09 21:01:58 -07:00
|
|
|
return Validator{
|
2018-05-18 15:57:47 -07:00
|
|
|
Owner: owner,
|
2018-05-10 16:02:35 -07:00
|
|
|
PubKey: pubKey,
|
2018-05-25 15:13:29 -07:00
|
|
|
Revoked: false,
|
2018-07-13 13:46:14 -07:00
|
|
|
Status: sdk.Unbonded,
|
|
|
|
Tokens: sdk.ZeroRat(),
|
2018-05-10 16:02:35 -07:00
|
|
|
DelegatorShares: sdk.ZeroRat(),
|
|
|
|
Description: description,
|
|
|
|
BondHeight: int64(0),
|
|
|
|
BondIntraTxCounter: int16(0),
|
|
|
|
ProposerRewardPool: sdk.Coins{},
|
|
|
|
Commission: sdk.ZeroRat(),
|
|
|
|
CommissionMax: sdk.ZeroRat(),
|
|
|
|
CommissionChangeRate: sdk.ZeroRat(),
|
|
|
|
CommissionChangeToday: sdk.ZeroRat(),
|
2018-07-13 13:46:14 -07:00
|
|
|
LastBondedTokens: sdk.ZeroRat(),
|
2018-01-25 19:31:07 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 22:32:49 -07:00
|
|
|
// what's kept in the store value
|
|
|
|
type validatorValue struct {
|
|
|
|
PubKey crypto.PubKey
|
|
|
|
Revoked bool
|
2018-07-13 13:46:14 -07:00
|
|
|
Status sdk.BondStatus
|
|
|
|
Tokens sdk.Rat
|
2018-07-03 22:32:49 -07:00
|
|
|
DelegatorShares sdk.Rat
|
|
|
|
Description Description
|
|
|
|
BondHeight int64
|
|
|
|
BondIntraTxCounter int16
|
|
|
|
ProposerRewardPool sdk.Coins
|
|
|
|
Commission sdk.Rat
|
|
|
|
CommissionMax sdk.Rat
|
|
|
|
CommissionChangeRate sdk.Rat
|
|
|
|
CommissionChangeToday sdk.Rat
|
2018-07-13 13:46:14 -07:00
|
|
|
LastBondedTokens sdk.Rat
|
2018-07-03 22:32:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// return the redelegation without fields contained within the key for the store
|
2018-07-04 14:07:06 -07:00
|
|
|
func MustMarshalValidator(cdc *wire.Codec, validator Validator) []byte {
|
2018-07-03 22:32:49 -07:00
|
|
|
val := validatorValue{
|
|
|
|
PubKey: validator.PubKey,
|
|
|
|
Revoked: validator.Revoked,
|
2018-07-13 13:46:14 -07:00
|
|
|
Status: validator.Status,
|
|
|
|
Tokens: validator.Tokens,
|
2018-07-03 22:32:49 -07:00
|
|
|
DelegatorShares: validator.DelegatorShares,
|
|
|
|
Description: validator.Description,
|
|
|
|
BondHeight: validator.BondHeight,
|
|
|
|
BondIntraTxCounter: validator.BondIntraTxCounter,
|
|
|
|
ProposerRewardPool: validator.ProposerRewardPool,
|
|
|
|
Commission: validator.Commission,
|
|
|
|
CommissionMax: validator.CommissionMax,
|
|
|
|
CommissionChangeRate: validator.CommissionChangeRate,
|
|
|
|
CommissionChangeToday: validator.CommissionChangeToday,
|
2018-07-13 13:46:14 -07:00
|
|
|
LastBondedTokens: validator.LastBondedTokens,
|
2018-07-03 22:32:49 -07:00
|
|
|
}
|
|
|
|
return cdc.MustMarshalBinary(val)
|
|
|
|
}
|
|
|
|
|
|
|
|
// unmarshal a redelegation from a store key and value
|
2018-07-04 14:07:06 -07:00
|
|
|
func MustUnmarshalValidator(cdc *wire.Codec, ownerAddr, value []byte) Validator {
|
|
|
|
validator, err := UnmarshalValidator(cdc, ownerAddr, value)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return validator
|
|
|
|
}
|
|
|
|
|
|
|
|
// unmarshal a redelegation from a store key and value
|
|
|
|
func UnmarshalValidator(cdc *wire.Codec, ownerAddr, value []byte) (validator Validator, err error) {
|
2018-07-03 22:32:49 -07:00
|
|
|
var storeValue validatorValue
|
2018-07-04 14:07:06 -07:00
|
|
|
err = cdc.UnmarshalBinary(value, &storeValue)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2018-07-03 22:32:49 -07:00
|
|
|
|
|
|
|
if len(ownerAddr) != 20 {
|
2018-07-04 14:07:06 -07:00
|
|
|
err = errors.New("unexpected address length")
|
|
|
|
return
|
2018-07-03 22:32:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return Validator{
|
|
|
|
Owner: ownerAddr,
|
|
|
|
PubKey: storeValue.PubKey,
|
|
|
|
Revoked: storeValue.Revoked,
|
2018-07-13 13:46:14 -07:00
|
|
|
Tokens: storeValue.Tokens,
|
|
|
|
Status: storeValue.Status,
|
2018-07-03 22:32:49 -07:00
|
|
|
DelegatorShares: storeValue.DelegatorShares,
|
|
|
|
Description: storeValue.Description,
|
|
|
|
BondHeight: storeValue.BondHeight,
|
|
|
|
BondIntraTxCounter: storeValue.BondIntraTxCounter,
|
|
|
|
ProposerRewardPool: storeValue.ProposerRewardPool,
|
|
|
|
Commission: storeValue.Commission,
|
|
|
|
CommissionMax: storeValue.CommissionMax,
|
|
|
|
CommissionChangeRate: storeValue.CommissionChangeRate,
|
|
|
|
CommissionChangeToday: storeValue.CommissionChangeToday,
|
2018-07-13 13:46:14 -07:00
|
|
|
LastBondedTokens: storeValue.LastBondedTokens,
|
2018-07-04 14:07:06 -07:00
|
|
|
}, nil
|
2018-07-03 22:32:49 -07:00
|
|
|
}
|
|
|
|
|
2018-07-18 13:09:40 -07:00
|
|
|
// HumanReadableString returns a human readable string representation of a
|
|
|
|
// validator. An error is returned if the owner or the owner's public key
|
|
|
|
// cannot be converted to Bech32 format.
|
|
|
|
func (v Validator) HumanReadableString() (string, error) {
|
|
|
|
bechVal, err := sdk.Bech32ifyValPub(v.PubKey)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
resp := "Validator \n"
|
|
|
|
resp += fmt.Sprintf("Owner: %s\n", v.Owner)
|
|
|
|
resp += fmt.Sprintf("Validator: %s\n", bechVal)
|
|
|
|
resp += fmt.Sprintf("Revoked: %v\n", v.Revoked)
|
|
|
|
resp += fmt.Sprintf("Status: %s\n", sdk.BondStatusToString(v.Status))
|
|
|
|
resp += fmt.Sprintf("Tokens: %s\n", v.Tokens.FloatString())
|
|
|
|
resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares.FloatString())
|
|
|
|
resp += fmt.Sprintf("Description: %s\n", v.Description)
|
|
|
|
resp += fmt.Sprintf("Bond Height: %d\n", v.BondHeight)
|
|
|
|
resp += fmt.Sprintf("Proposer Reward Pool: %s\n", v.ProposerRewardPool.String())
|
|
|
|
resp += fmt.Sprintf("Commission: %s\n", v.Commission.String())
|
|
|
|
resp += fmt.Sprintf("Max Commission Rate: %s\n", v.CommissionMax.String())
|
|
|
|
resp += fmt.Sprintf("Commission Change Rate: %s\n", v.CommissionChangeRate.String())
|
|
|
|
resp += fmt.Sprintf("Commission Change Today: %s\n", v.CommissionChangeToday.String())
|
|
|
|
resp += fmt.Sprintf("Previous Bonded Tokens: %s\n", v.LastBondedTokens.String())
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
}
|
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
//___________________________________________________________________
|
|
|
|
|
|
|
|
// validator struct for bech output
|
|
|
|
type BechValidator struct {
|
|
|
|
Owner sdk.AccAddress `json:"owner"` // in bech32
|
|
|
|
PubKey string `json:"pub_key"` // in bech32
|
|
|
|
Revoked bool `json:"revoked"` // has the validator been revoked from bonded status?
|
|
|
|
|
|
|
|
Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded)
|
|
|
|
Tokens sdk.Rat `json:"tokens"` // delegated tokens (incl. self-delegation)
|
|
|
|
DelegatorShares sdk.Rat `json:"delegator_shares"` // total shares issued to a validator's delegators
|
|
|
|
|
|
|
|
Description Description `json:"description"` // description terms for the validator
|
|
|
|
BondHeight int64 `json:"bond_height"` // earliest height as a bonded validator
|
|
|
|
BondIntraTxCounter int16 `json:"bond_intra_tx_counter"` // block-local tx index of validator change
|
|
|
|
ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer
|
|
|
|
|
|
|
|
Commission sdk.Rat `json:"commission"` // XXX the commission rate of fees charged to any delegators
|
|
|
|
CommissionMax sdk.Rat `json:"commission_max"` // XXX maximum commission rate which this validator can ever charge
|
|
|
|
CommissionChangeRate sdk.Rat `json:"commission_change_rate"` // XXX maximum daily increase of the validator commission
|
|
|
|
CommissionChangeToday sdk.Rat `json:"commission_change_today"` // XXX commission rate change today, reset each day (UTC time)
|
|
|
|
|
|
|
|
// fee related
|
|
|
|
LastBondedTokens sdk.Rat `json:"prev_bonded_shares"` // last bonded token amount
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the bech validator from the the regular validator
|
|
|
|
func (v Validator) Bech32Validator() (BechValidator, error) {
|
|
|
|
bechValPubkey, err := sdk.Bech32ifyValPub(v.PubKey)
|
|
|
|
if err != nil {
|
|
|
|
return BechValidator{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return BechValidator{
|
|
|
|
Owner: v.Owner,
|
|
|
|
PubKey: bechValPubkey,
|
|
|
|
Revoked: v.Revoked,
|
|
|
|
|
|
|
|
Status: v.Status,
|
|
|
|
Tokens: v.Tokens,
|
|
|
|
DelegatorShares: v.DelegatorShares,
|
|
|
|
|
|
|
|
Description: v.Description,
|
|
|
|
BondHeight: v.BondHeight,
|
|
|
|
BondIntraTxCounter: v.BondIntraTxCounter,
|
|
|
|
ProposerRewardPool: v.ProposerRewardPool,
|
|
|
|
|
|
|
|
Commission: v.Commission,
|
|
|
|
CommissionMax: v.CommissionMax,
|
|
|
|
CommissionChangeRate: v.CommissionChangeRate,
|
|
|
|
CommissionChangeToday: v.CommissionChangeToday,
|
|
|
|
|
|
|
|
LastBondedTokens: v.LastBondedTokens,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
//___________________________________________________________________
|
|
|
|
|
2018-05-12 15:22:59 -07:00
|
|
|
// only the vitals - does not check bond height of IntraTxCounter
|
2018-07-13 13:46:14 -07:00
|
|
|
// nolint gocyclo - why dis fail?
|
2018-06-26 19:00:12 -07:00
|
|
|
func (v Validator) Equal(c2 Validator) bool {
|
2018-05-20 14:39:04 -07:00
|
|
|
return v.PubKey.Equals(c2.PubKey) &&
|
2018-05-18 15:57:47 -07:00
|
|
|
bytes.Equal(v.Owner, c2.Owner) &&
|
2018-07-13 13:46:14 -07:00
|
|
|
v.Status.Equal(c2.Status) &&
|
|
|
|
v.Tokens.Equal(c2.Tokens) &&
|
2018-05-09 21:01:58 -07:00
|
|
|
v.DelegatorShares.Equal(c2.DelegatorShares) &&
|
|
|
|
v.Description == c2.Description &&
|
|
|
|
v.ProposerRewardPool.IsEqual(c2.ProposerRewardPool) &&
|
|
|
|
v.Commission.Equal(c2.Commission) &&
|
|
|
|
v.CommissionMax.Equal(c2.CommissionMax) &&
|
|
|
|
v.CommissionChangeRate.Equal(c2.CommissionChangeRate) &&
|
|
|
|
v.CommissionChangeToday.Equal(c2.CommissionChangeToday) &&
|
2018-07-13 13:46:14 -07:00
|
|
|
v.LastBondedTokens.Equal(c2.LastBondedTokens)
|
2018-04-30 23:07:06 -07:00
|
|
|
}
|
|
|
|
|
2018-05-09 21:01:58 -07:00
|
|
|
// Description - description fields for a validator
|
2018-03-26 07:48:15 -07:00
|
|
|
type Description struct {
|
2018-05-23 12:42:37 -07:00
|
|
|
Moniker string `json:"moniker"` // name
|
|
|
|
Identity string `json:"identity"` // optional identity signature (ex. UPort or Keybase)
|
|
|
|
Website string `json:"website"` // optional website link
|
|
|
|
Details string `json:"details"` // optional details
|
2018-03-26 07:48:15 -07:00
|
|
|
}
|
|
|
|
|
2018-07-03 21:21:36 -07:00
|
|
|
// NewDescription returns a new Description with the provided values.
|
2018-03-26 07:48:15 -07:00
|
|
|
func NewDescription(moniker, identity, website, details string) Description {
|
|
|
|
return Description{
|
|
|
|
Moniker: moniker,
|
|
|
|
Identity: identity,
|
|
|
|
Website: website,
|
|
|
|
Details: details,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
|
2018-06-26 19:00:12 -07:00
|
|
|
func (d Description) UpdateDescription(d2 Description) (Description, sdk.Error) {
|
2018-07-25 16:05:43 -07:00
|
|
|
if d2.Moniker == doNotModifyDescVal {
|
2018-06-26 19:00:12 -07:00
|
|
|
d2.Moniker = d.Moniker
|
|
|
|
}
|
2018-07-25 16:05:43 -07:00
|
|
|
if d2.Identity == doNotModifyDescVal {
|
2018-06-26 19:00:12 -07:00
|
|
|
d2.Identity = d.Identity
|
|
|
|
}
|
2018-07-25 16:05:43 -07:00
|
|
|
if d2.Website == doNotModifyDescVal {
|
2018-06-26 19:00:12 -07:00
|
|
|
d2.Website = d.Website
|
|
|
|
}
|
2018-07-25 16:05:43 -07:00
|
|
|
if d2.Details == doNotModifyDescVal {
|
2018-06-26 19:00:12 -07:00
|
|
|
d2.Details = d.Details
|
|
|
|
}
|
2018-07-03 21:21:36 -07:00
|
|
|
|
2018-06-26 19:00:12 -07:00
|
|
|
return Description{
|
|
|
|
Moniker: d2.Moniker,
|
|
|
|
Identity: d2.Identity,
|
|
|
|
Website: d2.Website,
|
|
|
|
Details: d2.Details,
|
|
|
|
}.EnsureLength()
|
|
|
|
}
|
|
|
|
|
2018-07-03 21:21:36 -07:00
|
|
|
// EnsureLength ensures the length of a validator's description.
|
2018-06-26 19:00:12 -07:00
|
|
|
func (d Description) EnsureLength() (Description, sdk.Error) {
|
|
|
|
if len(d.Moniker) > 70 {
|
|
|
|
return d, ErrDescriptionLength(DefaultCodespace, "moniker", len(d.Moniker), 70)
|
|
|
|
}
|
|
|
|
if len(d.Identity) > 3000 {
|
|
|
|
return d, ErrDescriptionLength(DefaultCodespace, "identity", len(d.Identity), 3000)
|
|
|
|
}
|
|
|
|
if len(d.Website) > 140 {
|
|
|
|
return d, ErrDescriptionLength(DefaultCodespace, "website", len(d.Website), 140)
|
|
|
|
}
|
|
|
|
if len(d.Details) > 280 {
|
|
|
|
return d, ErrDescriptionLength(DefaultCodespace, "details", len(d.Details), 280)
|
|
|
|
}
|
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
|
|
|
|
2018-07-03 21:21:36 -07:00
|
|
|
// ABCIValidator returns an abci.Validator from a staked validator type.
|
2018-06-29 15:22:24 -07:00
|
|
|
func (v Validator) ABCIValidator() abci.Validator {
|
2018-05-06 07:18:45 -07:00
|
|
|
return abci.Validator{
|
2018-06-04 16:42:01 -07:00
|
|
|
PubKey: tmtypes.TM2PB.PubKey(v.PubKey),
|
2018-07-13 13:46:14 -07:00
|
|
|
Power: v.BondedTokens().RoundInt64(),
|
2018-04-04 20:22:13 -07:00
|
|
|
}
|
2018-01-31 18:56:46 -08:00
|
|
|
}
|
|
|
|
|
2018-07-03 21:21:36 -07:00
|
|
|
// ABCIValidatorZero returns an abci.Validator from a staked validator type
|
|
|
|
// with with zero power used for validator updates.
|
2018-06-29 15:22:24 -07:00
|
|
|
func (v Validator) ABCIValidatorZero() abci.Validator {
|
2018-05-06 07:18:45 -07:00
|
|
|
return abci.Validator{
|
2018-06-04 16:42:01 -07:00
|
|
|
PubKey: tmtypes.TM2PB.PubKey(v.PubKey),
|
2018-04-05 09:31:36 -07:00
|
|
|
Power: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
// UpdateStatus updates the location of the shares within a validator
|
|
|
|
// to reflect the new status
|
2018-05-20 14:39:04 -07:00
|
|
|
func (v Validator) UpdateStatus(pool Pool, NewStatus sdk.BondStatus) (Validator, Pool) {
|
2018-05-12 15:54:50 -07:00
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
switch v.Status {
|
2018-05-20 14:39:04 -07:00
|
|
|
case sdk.Unbonded:
|
2018-07-13 13:46:14 -07:00
|
|
|
|
|
|
|
switch NewStatus {
|
|
|
|
case sdk.Unbonded:
|
2018-05-20 14:39:04 -07:00
|
|
|
return v, pool
|
2018-07-13 13:46:14 -07:00
|
|
|
case sdk.Bonded:
|
|
|
|
pool = pool.looseTokensToBonded(v.Tokens)
|
2018-05-12 15:54:50 -07:00
|
|
|
}
|
2018-05-20 14:39:04 -07:00
|
|
|
case sdk.Unbonding:
|
2018-07-13 13:46:14 -07:00
|
|
|
|
|
|
|
switch NewStatus {
|
|
|
|
case sdk.Unbonding:
|
2018-05-20 14:39:04 -07:00
|
|
|
return v, pool
|
2018-07-13 13:46:14 -07:00
|
|
|
case sdk.Bonded:
|
|
|
|
pool = pool.looseTokensToBonded(v.Tokens)
|
2018-05-12 15:54:50 -07:00
|
|
|
}
|
2018-05-20 14:39:04 -07:00
|
|
|
case sdk.Bonded:
|
2018-07-13 13:46:14 -07:00
|
|
|
|
|
|
|
switch NewStatus {
|
|
|
|
case sdk.Bonded:
|
2018-05-20 14:39:04 -07:00
|
|
|
return v, pool
|
2018-07-13 13:46:14 -07:00
|
|
|
default:
|
|
|
|
pool = pool.bondedTokensToLoose(v.Tokens)
|
2018-05-12 15:54:50 -07:00
|
|
|
}
|
|
|
|
}
|
2018-07-03 21:21:36 -07:00
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
v.Status = NewStatus
|
2018-05-20 14:39:04 -07:00
|
|
|
return v, pool
|
2018-05-12 15:54:50 -07:00
|
|
|
}
|
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
// removes tokens from a validator
|
|
|
|
func (v Validator) RemoveTokens(pool Pool, tokens sdk.Rat) (Validator, Pool) {
|
|
|
|
if v.Status == sdk.Bonded {
|
|
|
|
pool = pool.bondedTokensToLoose(tokens)
|
2018-05-24 16:03:26 -07:00
|
|
|
}
|
2018-07-03 21:21:36 -07:00
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
v.Tokens = v.Tokens.Sub(tokens)
|
|
|
|
return v, pool
|
2018-05-12 15:54:50 -07:00
|
|
|
}
|
|
|
|
|
2018-05-15 20:32:18 -07:00
|
|
|
//_________________________________________________________________________________________________________
|
2018-05-12 15:54:50 -07:00
|
|
|
|
2018-07-03 21:21:36 -07:00
|
|
|
// AddTokensFromDel adds tokens to a validator
|
|
|
|
func (v Validator) AddTokensFromDel(pool Pool, amount int64) (Validator, Pool, sdk.Rat) {
|
2018-05-12 15:54:50 -07:00
|
|
|
|
2018-07-03 21:21:36 -07:00
|
|
|
// bondedShare/delegatedShare
|
2018-07-13 13:46:14 -07:00
|
|
|
exRate := v.DelegatorShareExRate()
|
|
|
|
amountRat := sdk.NewRat(amount)
|
2018-05-15 21:41:21 -07:00
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
if v.Status == sdk.Bonded {
|
|
|
|
pool = pool.looseTokensToBonded(amountRat)
|
2018-05-12 15:54:50 -07:00
|
|
|
}
|
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
v.Tokens = v.Tokens.Add(amountRat)
|
|
|
|
issuedShares := amountRat.Quo(exRate)
|
|
|
|
v.DelegatorShares = v.DelegatorShares.Add(issuedShares)
|
2018-05-12 15:54:50 -07:00
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
return v, pool, issuedShares
|
2018-05-12 15:54:50 -07:00
|
|
|
}
|
|
|
|
|
2018-07-03 21:21:36 -07:00
|
|
|
// RemoveDelShares removes delegator shares from a validator.
|
2018-07-13 13:46:14 -07:00
|
|
|
func (v Validator) RemoveDelShares(pool Pool, delShares sdk.Rat) (Validator, Pool, sdk.Rat) {
|
|
|
|
issuedTokens := v.DelegatorShareExRate().Mul(delShares)
|
|
|
|
v.Tokens = v.Tokens.Sub(issuedTokens)
|
2018-05-12 15:54:50 -07:00
|
|
|
v.DelegatorShares = v.DelegatorShares.Sub(delShares)
|
2018-05-15 06:06:56 -07:00
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
if v.Status == sdk.Bonded {
|
|
|
|
pool = pool.bondedTokensToLoose(issuedTokens)
|
2018-05-15 06:06:56 -07:00
|
|
|
}
|
2018-07-03 21:21:36 -07:00
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
return v, pool, issuedTokens
|
2018-05-12 15:54:50 -07:00
|
|
|
}
|
2018-05-06 07:18:45 -07:00
|
|
|
|
2018-07-03 21:21:36 -07:00
|
|
|
// DelegatorShareExRate gets the exchange rate of tokens over delegator shares.
|
2018-07-13 13:46:14 -07:00
|
|
|
// UNITS: tokens/delegator-shares
|
|
|
|
func (v Validator) DelegatorShareExRate() sdk.Rat {
|
2018-05-15 21:41:21 -07:00
|
|
|
if v.DelegatorShares.IsZero() {
|
|
|
|
return sdk.OneRat()
|
|
|
|
}
|
2018-07-13 13:46:14 -07:00
|
|
|
return v.Tokens.Quo(v.DelegatorShares)
|
|
|
|
}
|
2018-07-03 21:21:36 -07:00
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
// Get the bonded tokens which the validator holds
|
|
|
|
func (v Validator) BondedTokens() sdk.Rat {
|
|
|
|
if v.Status == sdk.Bonded {
|
|
|
|
return v.Tokens
|
|
|
|
}
|
|
|
|
return sdk.ZeroRat()
|
2018-05-15 21:41:21 -07:00
|
|
|
}
|
|
|
|
|
2018-05-09 18:39:14 -07:00
|
|
|
//______________________________________________________________________
|
2018-05-06 07:18:45 -07:00
|
|
|
|
2018-05-09 18:39:14 -07:00
|
|
|
// ensure fulfills the sdk validator types
|
|
|
|
var _ sdk.Validator = Validator{}
|
2018-05-06 07:18:45 -07:00
|
|
|
|
2018-05-09 18:39:14 -07:00
|
|
|
// nolint - for sdk.Validator
|
2018-06-29 20:34:55 -07:00
|
|
|
func (v Validator) GetRevoked() bool { return v.Revoked }
|
2018-06-21 17:19:14 -07:00
|
|
|
func (v Validator) GetMoniker() string { return v.Description.Moniker }
|
2018-07-13 13:46:14 -07:00
|
|
|
func (v Validator) GetStatus() sdk.BondStatus { return v.Status }
|
2018-07-06 00:06:53 -07:00
|
|
|
func (v Validator) GetOwner() sdk.AccAddress { return v.Owner }
|
2018-06-21 17:19:14 -07:00
|
|
|
func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey }
|
2018-07-13 13:46:14 -07:00
|
|
|
func (v Validator) GetPower() sdk.Rat { return v.BondedTokens() }
|
2018-07-18 00:42:18 -07:00
|
|
|
func (v Validator) GetTokens() sdk.Rat { return v.Tokens }
|
2018-06-21 17:19:14 -07:00
|
|
|
func (v Validator) GetDelegatorShares() sdk.Rat { return v.DelegatorShares }
|
|
|
|
func (v Validator) GetBondHeight() int64 { return v.BondHeight }
|