2018-05-09 18:39:14 -07:00
|
|
|
package types
|
|
|
|
|
|
|
|
import (
|
2019-02-13 15:01:50 -08:00
|
|
|
"math/big"
|
|
|
|
|
2018-06-28 17:54:47 -07:00
|
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
|
|
"github.com/tendermint/tendermint/crypto"
|
2018-05-09 18:39:14 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
// status of a validator
|
2018-05-11 14:58:28 -07:00
|
|
|
type BondStatus byte
|
2018-05-09 18:39:14 -07:00
|
|
|
|
2019-02-13 15:01:50 -08:00
|
|
|
// staking constants
|
2018-05-09 18:39:14 -07:00
|
|
|
const (
|
2018-05-15 20:32:18 -07:00
|
|
|
Unbonded BondStatus = 0x00
|
2018-05-11 14:58:28 -07:00
|
|
|
Unbonding BondStatus = 0x01
|
2018-05-15 20:32:18 -07:00
|
|
|
Bonded BondStatus = 0x02
|
2019-02-13 15:01:50 -08:00
|
|
|
|
|
|
|
// default bond denomination
|
|
|
|
DefaultBondDenom = "stake"
|
|
|
|
|
|
|
|
// Delay, in blocks, between when validator updates are returned to Tendermint and when they are applied.
|
|
|
|
// For example, if this is 0, the validator set at the end of a block will sign the next block, or
|
|
|
|
// if this is 1, the validator set at the end of a block will sign the block after the next.
|
|
|
|
// Constant as this should not change without a hard fork.
|
|
|
|
// TODO: Link to some Tendermint docs, this is very unobvious.
|
|
|
|
ValidatorUpdateDelay int64 = 1
|
2018-05-09 18:39:14 -07:00
|
|
|
)
|
|
|
|
|
2018-05-26 14:21:29 -07:00
|
|
|
//BondStatusToString for pretty prints of Bond Status
|
|
|
|
func BondStatusToString(b BondStatus) string {
|
|
|
|
switch b {
|
|
|
|
case 0x00:
|
2018-05-28 16:27:34 -07:00
|
|
|
return "Unbonded"
|
2018-05-26 14:21:29 -07:00
|
|
|
case 0x01:
|
|
|
|
return "Unbonding"
|
|
|
|
case 0x02:
|
|
|
|
return "Bonded"
|
|
|
|
default:
|
2018-07-13 13:46:14 -07:00
|
|
|
panic("improper use of BondStatusToString")
|
2018-05-26 14:21:29 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-13 15:01:50 -08:00
|
|
|
// PowerReduction is the amount of staking tokens required for 1 unit of Tendermint power
|
|
|
|
var PowerReduction = NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(6), nil))
|
|
|
|
|
|
|
|
// TokensToTendermintPower - convert input tokens to potential tendermint power
|
|
|
|
func TokensToTendermintPower(tokens Int) int64 {
|
2019-02-21 09:35:55 -08:00
|
|
|
return (tokens.Quo(PowerReduction)).Int64()
|
2019-02-13 15:01:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// TokensFromTendermintPower - convert input power to tokens
|
|
|
|
func TokensFromTendermintPower(power int64) Int {
|
|
|
|
return NewInt(power).Mul(PowerReduction)
|
|
|
|
}
|
|
|
|
|
2018-07-13 13:46:14 -07:00
|
|
|
// nolint
|
|
|
|
func (b BondStatus) Equal(b2 BondStatus) bool {
|
|
|
|
return byte(b) == byte(b2)
|
|
|
|
}
|
|
|
|
|
2018-05-09 18:39:14 -07:00
|
|
|
// validator for a delegated proof of stake system
|
|
|
|
type Validator interface {
|
2019-04-02 06:43:22 -07:00
|
|
|
IsJailed() bool // whether the validator is jailed
|
2019-03-25 14:13:02 -07:00
|
|
|
GetMoniker() string // moniker of the validator
|
|
|
|
GetStatus() BondStatus // status of the validator
|
|
|
|
GetOperator() ValAddress // operator address to receive/return validators coins
|
|
|
|
GetConsPubKey() crypto.PubKey // validation consensus pubkey
|
|
|
|
GetConsAddr() ConsAddress // validation consensus address
|
|
|
|
GetTokens() Int // validation tokens
|
|
|
|
GetBondedTokens() Int // validator bonded tokens
|
|
|
|
GetTendermintPower() int64 // validation power in tendermint
|
|
|
|
GetCommission() Dec // validator commission rate
|
|
|
|
GetMinSelfDelegation() Int // validator minimum self delegation
|
|
|
|
GetDelegatorShares() Dec // total outstanding delegator shares
|
|
|
|
TokensFromShares(Dec) Dec // token worth of provided delegator shares
|
|
|
|
TokensFromSharesTruncated(Dec) Dec // token worth of provided delegator shares, truncated
|
|
|
|
SharesFromTokens(amt Int) (Dec, Error) // shares worth of delegator's bond
|
|
|
|
SharesFromTokensTruncated(amt Int) (Dec, Error) // truncated shares worth of delegator's bond
|
2018-05-09 18:39:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// validator which fulfills abci validator interface for use in Tendermint
|
|
|
|
func ABCIValidator(v Validator) abci.Validator {
|
|
|
|
return abci.Validator{
|
2018-09-25 14:43:26 -07:00
|
|
|
Address: v.GetConsPubKey().Address(),
|
2019-02-05 21:30:48 -08:00
|
|
|
Power: v.GetTendermintPower(),
|
2018-05-09 18:39:14 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// properties for the set of all validators
|
|
|
|
type ValidatorSet interface {
|
2018-09-08 01:44:58 -07:00
|
|
|
// iterate through validators by operator address, execute func for each validator
|
2018-05-17 11:09:35 -07:00
|
|
|
IterateValidators(Context,
|
|
|
|
func(index int64, validator Validator) (stop bool))
|
|
|
|
|
2018-09-08 01:44:58 -07:00
|
|
|
// iterate through bonded validators by operator address, execute func for each validator
|
2018-11-04 20:44:43 -08:00
|
|
|
IterateBondedValidatorsByPower(Context,
|
|
|
|
func(index int64, validator Validator) (stop bool))
|
|
|
|
|
|
|
|
// iterate through the consensus validator set of the last block by operator address, execute func for each validator
|
|
|
|
IterateLastValidators(Context,
|
2018-05-17 11:09:35 -07:00
|
|
|
func(index int64, validator Validator) (stop bool))
|
|
|
|
|
2018-09-25 14:43:26 -07:00
|
|
|
Validator(Context, ValAddress) Validator // get a particular validator by operator address
|
|
|
|
ValidatorByConsAddr(Context, ConsAddress) Validator // get a particular validator by consensus address
|
2019-02-15 07:55:21 -08:00
|
|
|
TotalBondedTokens(Context) Int // total bonded tokens within the validator set
|
|
|
|
TotalTokens(Context) Int // total token supply
|
2018-06-26 19:00:12 -07:00
|
|
|
|
2018-06-29 20:34:55 -07:00
|
|
|
// slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction
|
2018-09-20 12:36:32 -07:00
|
|
|
Slash(Context, ConsAddress, int64, int64, Dec)
|
|
|
|
Jail(Context, ConsAddress) // jail a validator
|
|
|
|
Unjail(Context, ConsAddress) // unjail a validator
|
2018-08-31 12:21:12 -07:00
|
|
|
|
|
|
|
// Delegation allows for getting a particular delegation for a given validator
|
|
|
|
// and delegator outside the scope of the staking module.
|
|
|
|
Delegation(Context, AccAddress, ValAddress) Delegation
|
2018-05-09 18:39:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//_______________________________________________________________________________
|
|
|
|
|
|
|
|
// delegation bond for a delegated proof of stake system
|
|
|
|
type Delegation interface {
|
2018-10-22 01:18:10 -07:00
|
|
|
GetDelegatorAddr() AccAddress // delegator AccAddress for the bond
|
|
|
|
GetValidatorAddr() ValAddress // validator operator address
|
|
|
|
GetShares() Dec // amount of validator's shares held in this delegation
|
2018-05-09 18:39:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// properties for the set of all delegations for a particular
|
|
|
|
type DelegationSet interface {
|
2018-06-21 17:19:14 -07:00
|
|
|
GetValidatorSet() ValidatorSet // validator set for which delegation set is based upon
|
2018-05-09 18:39:14 -07:00
|
|
|
|
2018-07-06 00:06:53 -07:00
|
|
|
// iterate through all delegations from one delegator by validator-AccAddress,
|
2018-05-17 11:09:35 -07:00
|
|
|
// execute func for each validator
|
2018-07-06 00:06:53 -07:00
|
|
|
IterateDelegations(ctx Context, delegator AccAddress,
|
2018-05-17 11:09:35 -07:00
|
|
|
fn func(index int64, delegation Delegation) (stop bool))
|
2018-05-09 18:39:14 -07:00
|
|
|
}
|
2018-08-31 17:01:23 -07:00
|
|
|
|
2018-09-22 13:29:42 -07:00
|
|
|
//_______________________________________________________________________________
|
|
|
|
// Event Hooks
|
|
|
|
// These can be utilized to communicate between a staking keeper and another
|
|
|
|
// keeper which must take particular actions when validators/delegators change
|
|
|
|
// state. The second keeper must implement this interface, which then the
|
|
|
|
// staking keeper can call.
|
|
|
|
|
|
|
|
// TODO refactor event hooks out to the receiver modules
|
|
|
|
|
|
|
|
// event hooks for staking validator object
|
|
|
|
type StakingHooks interface {
|
2019-01-08 21:28:46 -08:00
|
|
|
AfterValidatorCreated(ctx Context, valAddr ValAddress) // Must be called when a validator is created
|
2019-01-15 07:34:48 -08:00
|
|
|
BeforeValidatorModified(ctx Context, valAddr ValAddress) // Must be called when a validator's state changes
|
2019-01-08 21:28:46 -08:00
|
|
|
AfterValidatorRemoved(ctx Context, consAddr ConsAddress, valAddr ValAddress) // Must be called when a validator is deleted
|
2018-09-22 13:29:42 -07:00
|
|
|
|
2019-01-08 21:28:46 -08:00
|
|
|
AfterValidatorBonded(ctx Context, consAddr ConsAddress, valAddr ValAddress) // Must be called when a validator is bonded
|
|
|
|
AfterValidatorBeginUnbonding(ctx Context, consAddr ConsAddress, valAddr ValAddress) // Must be called when a validator begins unbonding
|
2018-09-22 13:29:42 -07:00
|
|
|
|
2019-01-08 21:28:46 -08:00
|
|
|
BeforeDelegationCreated(ctx Context, delAddr AccAddress, valAddr ValAddress) // Must be called when a delegation is created
|
|
|
|
BeforeDelegationSharesModified(ctx Context, delAddr AccAddress, valAddr ValAddress) // Must be called when a delegation's shares are modified
|
|
|
|
BeforeDelegationRemoved(ctx Context, delAddr AccAddress, valAddr ValAddress) // Must be called when a delegation is removed
|
2019-01-16 13:38:05 -08:00
|
|
|
AfterDelegationModified(ctx Context, delAddr AccAddress, valAddr ValAddress)
|
|
|
|
BeforeValidatorSlashed(ctx Context, valAddr ValAddress, fraction Dec)
|
2018-09-17 20:02:15 -07:00
|
|
|
}
|