Merge PR #4417: cleanup staking references from types pkg

* cleanup staking references from types pkg

* check interface on runtime

* fixes

* rename validator set from slashing keeper

* final cleanup

* fix test

* fix querier

* fix tests

* rename interfaces

* update bond status

* fixes

* expected pkg

* ensure expected keepers match used funcs

* cha cha cha
This commit is contained in:
Federico Kunze 2019-06-05 00:06:58 +02:00 committed by Jack Zampolin
parent fe695b8f7b
commit d322e23425
36 changed files with 385 additions and 268 deletions

View File

@ -0,0 +1,2 @@
#3928 remove staking references from types package
#1528 define local module interfaces instead of /types

View File

@ -42,8 +42,8 @@ Each block the validator queue is to be checked for mature unbonding validators
(namely with a completion time <= current time). At this point any mature
validators which do not have any delegations remaining are deleted from state.
For all other mature unbonding validators that still have remaining
delegations, the validator.Status is switched from sdk.Unbonding to
sdk.Unbonded.
delegations, the `validator.Status` is switched from `sdk.Unbonding` to
`sdk.Unbonded`.
### Unbonding Delegations

View File

@ -11,6 +11,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// ExportAppStateAndValidators exports the state of the application for a genesis
@ -63,7 +64,7 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []str
/* Handle fee distribution state. */
// withdraw all validator commission
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.Validator) (stop bool) {
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val expected.ValidatorI) (stop bool) {
_, _ = app.distrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
return false
})
@ -85,7 +86,7 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []str
ctx = ctx.WithBlockHeight(0)
// reinitialize all validators
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.Validator) (stop bool) {
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val expected.ValidatorI) (stop bool) {
// donate any unwithdrawn outstanding reward fraction tokens to the community pool
scraps := app.distrKeeper.GetValidatorOutstandingRewards(ctx, val.GetOperator())

View File

@ -2,19 +2,10 @@ package types
import (
"math/big"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
)
// status of a validator
type BondStatus byte
// staking constants
const (
Unbonded BondStatus = 0x00
Unbonding BondStatus = 0x01
Bonded BondStatus = 0x02
// default bond denomination
DefaultBondDenom = "stake"
@ -25,26 +16,8 @@ const (
// Constant as this should not change without a hard fork.
// TODO: Link to some Tendermint docs, this is very unobvious.
ValidatorUpdateDelay int64 = 1
BondStatusUnbonded = "Unbonded"
BondStatusUnbonding = "Unbonding"
BondStatusBonded = "Bonded"
)
// String implements the Stringer interface for BondStatus.
func (b BondStatus) String() string {
switch b {
case 0x00:
return BondStatusUnbonded
case 0x01:
return BondStatusUnbonding
case 0x02:
return BondStatusBonded
default:
panic("invalid bond status")
}
}
// 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))
@ -58,112 +31,35 @@ func TokensFromTendermintPower(power int64) Int {
return NewInt(power).Mul(PowerReduction)
}
// nolint
// BondStatus is the status of a validator
type BondStatus byte
// staking constants
const (
Unbonded BondStatus = 0x00
Unbonding BondStatus = 0x01
Bonded BondStatus = 0x02
BondStatusUnbonded = "Unbonded"
BondStatusUnbonding = "Unbonding"
BondStatusBonded = "Bonded"
)
// Equal compares two BondStatus instances
func (b BondStatus) Equal(b2 BondStatus) bool {
return byte(b) == byte(b2)
}
// validator for a delegated proof of stake system
type Validator interface {
IsJailed() bool // whether the validator is jailed
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
TokensFromSharesRoundUp(Dec) Dec // token worth of provided delegator shares, rounded up
SharesFromTokens(amt Int) (Dec, Error) // shares worth of delegator's bond
SharesFromTokensTruncated(amt Int) (Dec, Error) // truncated shares worth of delegator's bond
}
// validator which fulfills abci validator interface for use in Tendermint
func ABCIValidator(v Validator) abci.Validator {
return abci.Validator{
Address: v.GetConsPubKey().Address(),
Power: v.GetTendermintPower(),
// String implements the Stringer interface for BondStatus.
func (b BondStatus) String() string {
switch b {
case 0x00:
return BondStatusUnbonded
case 0x01:
return BondStatusUnbonding
case 0x02:
return BondStatusBonded
default:
panic("invalid bond status")
}
}
// properties for the set of all validators
type ValidatorSet interface {
// iterate through validators by operator address, execute func for each validator
IterateValidators(Context,
func(index int64, validator Validator) (stop bool))
// iterate through bonded validators by operator address, execute func for each validator
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,
func(index int64, validator Validator) (stop bool))
Validator(Context, ValAddress) Validator // get a particular validator by operator address
ValidatorByConsAddr(Context, ConsAddress) Validator // get a particular validator by consensus address
TotalBondedTokens(Context) Int // total bonded tokens within the validator set
TotalTokens(Context) Int // total token supply
// slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction
Slash(Context, ConsAddress, int64, int64, Dec)
Jail(Context, ConsAddress) // jail a validator
Unjail(Context, ConsAddress) // unjail a validator
// 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
// MaxValidators returns the maximum amount of bonded validators
MaxValidators(Context) uint16
}
//_______________________________________________________________________________
// delegation bond for a delegated proof of stake system
type Delegation interface {
GetDelegatorAddr() AccAddress // delegator AccAddress for the bond
GetValidatorAddr() ValAddress // validator operator address
GetShares() Dec // amount of validator's shares held in this delegation
}
// properties for the set of all delegations for a particular
type DelegationSet interface {
GetValidatorSet() ValidatorSet // validator set for which delegation set is based upon
// iterate through all delegations from one delegator by validator-AccAddress,
// execute func for each validator
IterateDelegations(ctx Context, delegator AccAddress,
fn func(index int64, delegation Delegation) (stop bool))
}
//_______________________________________________________________________________
// 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 {
AfterValidatorCreated(ctx Context, valAddr ValAddress) // Must be called when a validator is created
BeforeValidatorModified(ctx Context, valAddr ValAddress) // Must be called when a validator's state changes
AfterValidatorRemoved(ctx Context, consAddr ConsAddress, valAddr ValAddress) // Must be called when a validator is deleted
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
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
AfterDelegationModified(ctx Context, delAddr AccAddress, valAddr ValAddress)
BeforeValidatorSlashed(ctx Context, valAddr ValAddress, fraction Dec)
}

View File

@ -6,6 +6,7 @@ import (
abci "github.com/tendermint/tendermint/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// allocate fees handles distribution of the collected fees
@ -82,8 +83,8 @@ func (k Keeper) AllocateTokens(ctx sdk.Context, sumPreviousPrecommitPower, total
}
// allocate tokens to a particular validator, splitting according to commission
func (k Keeper) AllocateTokensToValidator(ctx sdk.Context, val sdk.Validator, tokens sdk.DecCoins) {
// AllocateTokensToValidator allocate tokens to a particular validator, splitting according to commission
func (k Keeper) AllocateTokensToValidator(ctx sdk.Context, val expected.ValidatorI, tokens sdk.DecCoins) {
// split tokens between validator and delegators according to commission
commission := tokens.MulDec(val.GetCommission())

View File

@ -6,6 +6,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// initialize starting info for a new delegation
@ -27,7 +28,7 @@ func (k Keeper) initializeDelegation(ctx sdk.Context, val sdk.ValAddress, del sd
}
// calculate the rewards accrued by a delegation between two periods
func (k Keeper) calculateDelegationRewardsBetween(ctx sdk.Context, val sdk.Validator,
func (k Keeper) calculateDelegationRewardsBetween(ctx sdk.Context, val expected.ValidatorI,
startingPeriod, endingPeriod uint64, stake sdk.Dec) (rewards sdk.DecCoins) {
// sanity check
if startingPeriod > endingPeriod {
@ -52,7 +53,7 @@ func (k Keeper) calculateDelegationRewardsBetween(ctx sdk.Context, val sdk.Valid
}
// calculate the total rewards accrued by a delegation
func (k Keeper) calculateDelegationRewards(ctx sdk.Context, val sdk.Validator, del sdk.Delegation, endingPeriod uint64) (rewards sdk.DecCoins) {
func (k Keeper) calculateDelegationRewards(ctx sdk.Context, val expected.ValidatorI, del expected.DelegationI, endingPeriod uint64) (rewards sdk.DecCoins) {
// fetch starting info for delegation
startingInfo := k.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr())
@ -132,7 +133,7 @@ func (k Keeper) calculateDelegationRewards(ctx sdk.Context, val sdk.Validator, d
return rewards
}
func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val sdk.Validator, del sdk.Delegation) (sdk.Coins, sdk.Error) {
func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val expected.ValidatorI, del expected.DelegationI) (sdk.Coins, sdk.Error) {
// check existence of delegator starting info
if !k.HasDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr()) {
return nil, types.ErrNoDelegationDistInfo(k.codespace)

View File

@ -2,6 +2,7 @@ package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// Wrapper struct
@ -9,7 +10,7 @@ type Hooks struct {
k Keeper
}
var _ sdk.StakingHooks = Hooks{}
var _ types.StakingHooks = Hooks{}
// Create new distribution hooks
func (k Keeper) Hooks() Hooks { return Hooks{k} }
@ -19,8 +20,7 @@ func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
val := h.k.stakingKeeper.Validator(ctx, valAddr)
h.k.initializeValidator(ctx, val)
}
func (h Hooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
}
func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {
// fetch outstanding
@ -72,12 +72,14 @@ func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr
// clear current rewards
h.k.DeleteValidatorCurrentRewards(ctx, valAddr)
}
func (h Hooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
val := h.k.stakingKeeper.Validator(ctx, valAddr)
// increment period
h.k.incrementValidatorPeriod(ctx, val)
}
func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
val := h.k.stakingKeeper.Validator(ctx, valAddr)
del := h.k.stakingKeeper.Delegation(ctx, delAddr, valAddr)
@ -87,18 +89,19 @@ func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAd
panic(err)
}
}
func (h Hooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
// nothing needed here since BeforeDelegationSharesModified will always also be called
}
func (h Hooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
// create new delegation period record
h.k.initializeDelegation(ctx, valAddr, delAddr)
}
func (h Hooks) AfterValidatorBeginUnbonding(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {
}
func (h Hooks) AfterValidatorBonded(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {
}
func (h Hooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) {
// record the slash event
h.k.updateValidatorSlashFraction(ctx, valAddr, fraction)
}
// nolint - unused hooks
func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) {}
func (h Hooks) AfterValidatorBonded(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) {}
func (h Hooks) AfterValidatorBeginUnbonding(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) {}
func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {}

View File

@ -5,6 +5,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// register all distribution invariants
@ -75,7 +76,7 @@ func CanWithdrawInvariant(k Keeper) sdk.Invariant {
}
// iterate over all validators
k.stakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.Validator) (stop bool) {
k.stakingKeeper.IterateValidators(ctx, func(_ int64, val expected.ValidatorI) (stop bool) {
_, _ = k.WithdrawValidatorCommission(ctx, val.GetOperator())
delegationAddrs, ok := valDelegationAddrs[val.GetOperator().String()]
@ -108,7 +109,7 @@ func ReferenceCountInvariant(k Keeper) sdk.Invariant {
return func(ctx sdk.Context) error {
valCount := uint64(0)
k.stakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.Validator) (stop bool) {
k.stakingKeeper.IterateValidators(ctx, func(_ int64, val expected.ValidatorI) (stop bool) {
valCount++
return false
})

View File

@ -9,6 +9,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// nolint
@ -257,7 +258,7 @@ func queryDelegatorTotalRewards(ctx sdk.Context, _ []string, req abci.RequestQue
k.stakingKeeper.IterateDelegations(
ctx, params.DelegatorAddress,
func(_ int64, del sdk.Delegation) (stop bool) {
func(_ int64, del expected.DelegationI) (stop bool) {
valAddr := del.GetValidatorAddr()
val := k.stakingKeeper.Validator(ctx, valAddr)
endingPeriod := k.incrementValidatorPeriod(ctx, val)
@ -292,7 +293,7 @@ func queryDelegatorValidators(ctx sdk.Context, _ []string, req abci.RequestQuery
k.stakingKeeper.IterateDelegations(
ctx, params.DelegatorAddress,
func(_ int64, del sdk.Delegation) (stop bool) {
func(_ int64, del expected.DelegationI) (stop bool) {
validators = append(validators[:], del.GetValidatorAddr())
return false
},

View File

@ -4,10 +4,11 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// initialize rewards for a new validator
func (k Keeper) initializeValidator(ctx sdk.Context, val sdk.Validator) {
func (k Keeper) initializeValidator(ctx sdk.Context, val expected.ValidatorI) {
// set initial historical rewards (period 0) with reference count of 1
k.SetValidatorHistoricalRewards(ctx, val.GetOperator(), 0, types.NewValidatorHistoricalRewards(sdk.DecCoins{}, 1))
@ -22,7 +23,7 @@ func (k Keeper) initializeValidator(ctx sdk.Context, val sdk.Validator) {
}
// increment validator period, returning the period just ended
func (k Keeper) incrementValidatorPeriod(ctx sdk.Context, val sdk.Validator) uint64 {
func (k Keeper) incrementValidatorPeriod(ctx sdk.Context, val expected.ValidatorI) uint64 {
// fetch current rewards
rewards := k.GetValidatorCurrentRewards(ctx, val.GetOperator())

View File

@ -1,21 +1,60 @@
package types
import sdk "github.com/cosmos/cosmos-sdk/types"
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// expected staking keeper
// StakingKeeper expected staking keeper
type StakingKeeper interface {
// iterate through validators by operator address, execute func for each validator
IterateValidators(sdk.Context,
func(index int64, validator expected.ValidatorI) (stop bool))
// iterate through bonded validators by operator address, execute func for each validator
IterateBondedValidatorsByPower(sdk.Context,
func(index int64, validator expected.ValidatorI) (stop bool))
// iterate through the consensus validator set of the last block by operator address, execute func for each validator
IterateLastValidators(sdk.Context,
func(index int64, validator expected.ValidatorI) (stop bool))
Validator(sdk.Context, sdk.ValAddress) expected.ValidatorI // get a particular validator by operator address
ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) expected.ValidatorI // get a particular validator by consensus address
TotalBondedTokens(sdk.Context) sdk.Int // total bonded tokens within the validator set
TotalTokens(sdk.Context) sdk.Int // total token supply
// slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction
Slash(sdk.Context, sdk.ConsAddress, int64, int64, sdk.Dec)
Jail(sdk.Context, sdk.ConsAddress) // jail a validator
Unjail(sdk.Context, sdk.ConsAddress) // unjail a validator
// Delegation allows for getting a particular delegation for a given validator
// and delegator outside the scope of the staking module.
Delegation(sdk.Context, sdk.AccAddress, sdk.ValAddress) expected.DelegationI
// MaxValidators returns the maximum amount of bonded validators
MaxValidators(sdk.Context) uint16
IterateDelegations(ctx sdk.Context, delegator sdk.AccAddress,
fn func(index int64, delegation sdk.Delegation) (stop bool))
Delegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) sdk.Delegation
Validator(ctx sdk.Context, valAddr sdk.ValAddress) sdk.Validator
ValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) sdk.Validator
fn func(index int64, delegation expected.DelegationI) (stop bool))
GetLastTotalPower(ctx sdk.Context) sdk.Int
GetLastValidatorPower(ctx sdk.Context, valAddr sdk.ValAddress) int64
// used for invariants
IterateValidators(ctx sdk.Context,
fn func(index int64, validator sdk.Validator) (stop bool))
GetAllSDKDelegations(ctx sdk.Context) []sdk.Delegation
GetAllSDKDelegations(ctx sdk.Context) []staking.Delegation
}
// StakingHooks event hooks for staking validator object
type StakingHooks interface {
AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) // Must be called when a validator is created
AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator is deleted
BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) // Must be called when a delegation is created
BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) // Must be called when a delegation's shares are modified
AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress)
BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec)
}
// expected coin keeper

View File

@ -1,6 +1,9 @@
package gov
import sdk "github.com/cosmos/cosmos-sdk/types"
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// expected bank keeper
type BankKeeper interface {
@ -10,3 +13,15 @@ type BankKeeper interface {
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error
SetSendEnabled(ctx sdk.Context, enabled bool)
}
// StakingKeeper expected staking keeper (Validator and Delegator sets)
type StakingKeeper interface {
// iterate through bonded validators by operator address, execute func for each validator
IterateBondedValidatorsByPower(sdk.Context,
func(index int64, validator expected.ValidatorI) (stop bool))
TotalBondedTokens(sdk.Context) sdk.Int // total bonded tokens within the validator set
IterateDelegations(ctx sdk.Context, delegator sdk.AccAddress,
fn func(index int64, delegation expected.DelegationI) (stop bool))
}

View File

@ -30,11 +30,8 @@ type Keeper struct {
// The reference to the CoinKeeper to modify balances
ck BankKeeper
// The ValidatorSet to get information about validators
vs sdk.ValidatorSet
// The reference to the DelegationSet to get information about delegators
ds sdk.DelegationSet
// The reference to the DelegationSet and ValidatorSet to get information about validators and delegators
sk StakingKeeper
// The (unexposed) keys used to access the stores from the Context.
storeKey sdk.StoreKey
@ -56,7 +53,7 @@ type Keeper struct {
// - and tallying the result of the vote.
func NewKeeper(
cdc *codec.Codec, key sdk.StoreKey, paramsKeeper params.Keeper, paramSpace params.Subspace,
ck BankKeeper, ds sdk.DelegationSet, codespace sdk.CodespaceType, rtr Router,
ck BankKeeper, sk StakingKeeper, codespace sdk.CodespaceType, rtr Router,
) Keeper {
// It is vital to seal the governance proposal router here as to not allow
@ -69,8 +66,7 @@ func NewKeeper(
paramsKeeper: paramsKeeper,
paramSpace: paramSpace.WithKeyTable(ParamKeyTable()),
ck: ck,
ds: ds,
vs: ds.GetValidatorSet(),
sk: sk,
cdc: cdc,
codespace: codespace,
router: rtr,

View File

@ -2,6 +2,7 @@ package gov
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
"github.com/cosmos/cosmos-sdk/x/gov/types"
)
@ -38,7 +39,7 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, burn
currValidators := make(map[string]validatorGovInfo)
// fetch all the bonded validators, insert them into currValidators
keeper.vs.IterateBondedValidatorsByPower(ctx, func(index int64, validator sdk.Validator) (stop bool) {
keeper.sk.IterateBondedValidatorsByPower(ctx, func(index int64, validator expected.ValidatorI) (stop bool) {
currValidators[validator.GetOperator().String()] = newValidatorGovInfo(
validator.GetOperator(),
validator.GetBondedTokens(),
@ -59,7 +60,7 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, burn
currValidators[valAddrStr] = val
} else {
// iterate over all delegations from voter, deduct from any delegated-to validators
keeper.ds.IterateDelegations(ctx, vote.Voter, func(index int64, delegation sdk.Delegation) (stop bool) {
keeper.sk.IterateDelegations(ctx, vote.Voter, func(index int64, delegation expected.DelegationI) (stop bool) {
valAddrStr := delegation.GetValidatorAddr().String()
if val, ok := currValidators[valAddrStr]; ok {
@ -100,12 +101,12 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, burn
// TODO: Upgrade the spec to cover all of these cases & remove pseudocode.
// If there is no staked coins, the proposal fails
if keeper.vs.TotalBondedTokens(ctx).IsZero() {
if keeper.sk.TotalBondedTokens(ctx).IsZero() {
return false, false, tallyResults
}
// If there is not enough quorum of votes, the proposal fails
percentVoting := totalVotingPower.Quo(keeper.vs.TotalBondedTokens(ctx).ToDec())
percentVoting := totalVotingPower.Quo(keeper.sk.TotalBondedTokens(ctx).ToDec())
if percentVoting.LT(tallyParams.Quorum) {
return false, true, tallyResults
}

View File

@ -3,15 +3,40 @@ package slashing
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// expected staking keeper
type StakingKeeper interface {
IterateValidators(ctx sdk.Context,
fn func(index int64, validator sdk.Validator) (stop bool))
}
// expected bank keeper
// AccountKeeper expected account keeper
type AccountKeeper interface {
IterateAccounts(ctx sdk.Context, process func(auth.Account) (stop bool))
}
// StakingKeeper expected staking keeper
type StakingKeeper interface {
// iterate through validators by operator address, execute func for each validator
IterateValidators(sdk.Context,
func(index int64, validator expected.ValidatorI) (stop bool))
Validator(sdk.Context, sdk.ValAddress) expected.ValidatorI // get a particular validator by operator address
ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) expected.ValidatorI // get a particular validator by consensus address
// slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction
Slash(sdk.Context, sdk.ConsAddress, int64, int64, sdk.Dec)
Jail(sdk.Context, sdk.ConsAddress) // jail a validator
Unjail(sdk.Context, sdk.ConsAddress) // unjail a validator
// Delegation allows for getting a particular delegation for a given validator
// and delegator outside the scope of the staking module.
Delegation(sdk.Context, sdk.AccAddress, sdk.ValAddress) expected.DelegationI
// MaxValidators returns the maximum amount of bonded validators
MaxValidators(sdk.Context) uint16
}
// StakingHooks event hooks for staking validator object
type StakingHooks interface {
AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) // Must be called when a validator is created
AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator is deleted
AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator is bonded
}

View File

@ -5,6 +5,7 @@ import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// GenesisState - all slashing state that must be provided at genesis
@ -79,7 +80,7 @@ func ValidateGenesis(data GenesisState) error {
// and the keeper's address to pubkey map
func InitGenesis(ctx sdk.Context, keeper Keeper, stakingKeeper StakingKeeper, data GenesisState) {
stakingKeeper.IterateValidators(ctx,
func(index int64, validator sdk.Validator) bool {
func(index int64, validator expected.ValidatorI) bool {
keeper.addPubkey(ctx, validator.GetConsPubKey())
return false
},

View File

@ -24,13 +24,13 @@ func NewHandler(k Keeper) sdk.Handler {
// Validators must submit a transaction to unjail itself after
// having been jailed (and thus unbonded) for downtime
func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) sdk.Result {
validator := k.validatorSet.Validator(ctx, msg.ValidatorAddr)
validator := k.sk.Validator(ctx, msg.ValidatorAddr)
if validator == nil {
return ErrNoValidatorForAddress(k.codespace).Result()
}
// cannot be unjailed if no self-delegation exists
selfDel := k.validatorSet.Delegation(ctx, sdk.AccAddress(msg.ValidatorAddr), msg.ValidatorAddr)
selfDel := k.sk.Delegation(ctx, sdk.AccAddress(msg.ValidatorAddr), msg.ValidatorAddr)
if selfDel == nil {
return ErrMissingSelfDelegation(k.codespace).Result()
}
@ -62,7 +62,7 @@ func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) sdk.Result {
}
// unjail the validator
k.validatorSet.Unjail(ctx, consAddr)
k.sk.Unjail(ctx, consAddr)
tags := sdk.NewTags(
tags.Category, tags.TxCategory,

View File

@ -27,7 +27,7 @@ func (k Keeper) AfterValidatorBonded(ctx sdk.Context, address sdk.ConsAddress, _
// When a validator is created, add the address-pubkey relation.
func (k Keeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
validator := k.validatorSet.Validator(ctx, valAddr)
validator := k.sk.Validator(ctx, valAddr)
k.addPubkey(ctx, validator.GetConsPubKey())
}
@ -38,12 +38,12 @@ func (k Keeper) AfterValidatorRemoved(ctx sdk.Context, address sdk.ConsAddress)
//_________________________________________________________________________________________
// Wrapper struct
// Hooks wrapper struct for slashing keeper
type Hooks struct {
k Keeper
}
var _ sdk.StakingHooks = Hooks{}
var _ StakingHooks = Hooks{}
// Return the wrapper struct
func (k Keeper) Hooks() Hooks {

View File

@ -16,7 +16,7 @@ import (
type Keeper struct {
storeKey sdk.StoreKey
cdc *codec.Codec
validatorSet sdk.ValidatorSet
sk StakingKeeper
paramspace params.Subspace
// codespace
@ -24,11 +24,11 @@ type Keeper struct {
}
// NewKeeper creates a slashing keeper
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, vs sdk.ValidatorSet, paramspace params.Subspace, codespace sdk.CodespaceType) Keeper {
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, sk StakingKeeper, paramspace params.Subspace, codespace sdk.CodespaceType) Keeper {
keeper := Keeper{
storeKey: key,
cdc: cdc,
validatorSet: vs,
sk: sk,
paramspace: paramspace.WithKeyTable(ParamKeyTable()),
codespace: codespace,
}
@ -71,8 +71,8 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
}
// Get validator and signing info
validator := k.validatorSet.ValidatorByConsAddr(ctx, consAddr)
if validator == nil || validator.GetStatus() == sdk.Unbonded {
validator := k.sk.ValidatorByConsAddr(ctx, consAddr)
if validator == nil || validator.IsUnbonded() {
// Defensive.
// Simulation doesn't take unbonding periods into account, and
// Tendermint might break this assumption at some point.
@ -108,12 +108,12 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
// Tendermint. This value is validator.Tokens as sent to Tendermint via
// ABCI, and now received as evidence.
// The fraction is passed in to separately to slash unbonding and rebonding delegations.
k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, fraction)
k.sk.Slash(ctx, consAddr, distributionHeight, power, fraction)
// Jail validator if not already jailed
// begin unbonding validator if not already unbonding (tombstone)
if !validator.IsJailed() {
k.validatorSet.Jail(ctx, consAddr)
k.sk.Jail(ctx, consAddr)
}
// Set tombstoned to be true
@ -175,7 +175,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p
// if we are past the minimum height and the validator has missed too many blocks, punish them
if height > minHeight && signInfo.MissedBlocksCounter > maxMissed {
validator := k.validatorSet.ValidatorByConsAddr(ctx, consAddr)
validator := k.sk.ValidatorByConsAddr(ctx, consAddr)
if validator != nil && !validator.IsJailed() {
// Downtime confirmed: slash and jail the validator
@ -188,8 +188,8 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p
// i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block.
// That's fine since this is just used to filter unbonding delegations & redelegations.
distributionHeight := height - sdk.ValidatorUpdateDelay - 1
k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, k.SlashFractionDowntime(ctx))
k.validatorSet.Jail(ctx, consAddr)
k.sk.Slash(ctx, consAddr, distributionHeight, power, k.SlashFractionDowntime(ctx))
k.sk.Jail(ctx, consAddr)
signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeJailDuration(ctx))
// We need to reset the counter & array so that the validator won't be immediately slashed for downtime upon rebonding.

View File

@ -114,7 +114,7 @@ func TestPastMaxEvidenceAge(t *testing.T) {
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), power)
// should still be bonded
require.True(t, sk.Validator(ctx, operatorAddr).GetStatus() == sdk.Bonded)
require.True(t, sk.Validator(ctx, operatorAddr).IsBonded())
// should still have same power
require.Equal(t, oldPower, sk.Validator(ctx, operatorAddr).GetTendermintPower())

View File

@ -94,7 +94,7 @@ func querySigningInfos(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte
if params.Limit == 0 {
// set the default limit to max bonded if no limit was provided
params.Limit = int(k.validatorSet.MaxValidators(ctx))
params.Limit = int(k.sk.MaxValidators(ctx))
}
var signingInfos []ValidatorSigningInfo

View File

@ -0,0 +1,37 @@
package expected
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/tendermint/tendermint/crypto"
)
// DelegationI delegation bond for a delegated proof of stake system
type DelegationI interface {
GetDelegatorAddr() sdk.AccAddress // delegator sdk.AccAddress for the bond
GetValidatorAddr() sdk.ValAddress // validator operator address
GetShares() sdk.Dec // amount of validator's shares held in this delegation
}
// ValidatorI expected validator functions
type ValidatorI interface {
IsJailed() bool // whether the validator is jailed
GetMoniker() string // moniker of the validator
GetStatus() sdk.BondStatus // status of the validator
IsBonded() bool // check if has a bonded status
IsUnbonded() bool // check if has status unbonded
IsUnbonding() bool // check if has status unbonding
GetOperator() sdk.ValAddress // operator address to receive/return validators coins
GetConsPubKey() crypto.PubKey // validation consensus pubkey
GetConsAddr() sdk.ConsAddress // validation consensus address
GetTokens() sdk.Int // validation tokens
GetBondedTokens() sdk.Int // validator bonded tokens
GetTendermintPower() int64 // validation power in tendermint
GetCommission() sdk.Dec // validator commission rate
GetMinSelfDelegation() sdk.Int // validator minimum self delegation
GetDelegatorShares() sdk.Dec // total outstanding delegator shares
TokensFromShares(sdk.Dec) sdk.Dec // token worth of provided delegator shares
TokensFromSharesTruncated(sdk.Dec) sdk.Dec // token worth of provided delegator shares, truncated
TokensFromSharesRoundUp(sdk.Dec) sdk.Dec // token worth of provided delegator shares, rounded up
SharesFromTokens(amt sdk.Int) (sdk.Dec, sdk.Error) // shares worth of delegator's bond
SharesFromTokensTruncated(amt sdk.Int) (sdk.Dec, sdk.Error) // truncated shares worth of delegator's bond
}

View File

@ -8,6 +8,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
@ -53,7 +54,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, accountKeeper types.AccountKeep
}
// Set timeslice if necessary
if validator.Status == sdk.Unbonding {
if validator.IsUnbonding() {
keeper.InsertValidatorQueue(ctx, validator)
}
}
@ -143,7 +144,7 @@ func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
// WriteValidators returns a slice of bonded genesis validators.
func WriteValidators(ctx sdk.Context, keeper Keeper) (vals []tmtypes.GenesisValidator) {
keeper.IterateLastValidators(ctx, func(_ int64, validator sdk.Validator) (stop bool) {
keeper.IterateLastValidators(ctx, func(_ int64, validator expected.ValidatorI) (stop bool) {
vals = append(vals, tmtypes.GenesisValidator{
PubKey: validator.GetConsPubKey(),
Power: validator.GetTendermintPower(),
@ -179,10 +180,10 @@ func validateGenesisStateValidators(validators []types.Validator) (err error) {
if _, ok := addrMap[strKey]; ok {
return fmt.Errorf("duplicate validator in genesis state: moniker %v, address %v", val.Description.Moniker, val.ConsAddress())
}
if val.Jailed && val.Status == sdk.Bonded {
if val.Jailed && val.IsBonded() {
return fmt.Errorf("validator is bonded and jailed in genesis state: moniker %v, address %v", val.Description.Moniker, val.ConsAddress())
}
if val.DelegatorShares.IsZero() && val.Status != sdk.Unbonding {
if val.DelegatorShares.IsZero() && !val.IsUnbonding() {
return fmt.Errorf("bonded/unbonded genesis validator cannot have zero delegator shares, validator: %v", val)
}
addrMap[strKey] = true

View File

@ -702,7 +702,7 @@ func TestValidatorQueue(t *testing.T) {
validator, found := keeper.GetValidator(ctx, validatorAddr)
require.True(t, found)
require.True(t, validator.GetStatus() == sdk.Unbonding, "%v", validator)
require.True(t, validator.IsUnbonding(), "%v", validator)
// should still be unbonding at time 6 seconds later
ctx = ctx.WithBlockTime(origHeader.Time.Add(time.Second * 6))
@ -710,7 +710,7 @@ func TestValidatorQueue(t *testing.T) {
validator, found = keeper.GetValidator(ctx, validatorAddr)
require.True(t, found)
require.True(t, validator.GetStatus() == sdk.Unbonding, "%v", validator)
require.True(t, validator.IsUnbonding(), "%v", validator)
// should be in unbonded state at time 7 seconds later
ctx = ctx.WithBlockTime(origHeader.Time.Add(time.Second * 7))
@ -718,7 +718,7 @@ func TestValidatorQueue(t *testing.T) {
validator, found = keeper.GetValidator(ctx, validatorAddr)
require.True(t, found)
require.True(t, validator.GetStatus() == sdk.Unbonded, "%v", validator)
require.True(t, validator.IsUnbonded(), "%v", validator)
}
func TestUnbondingPeriod(t *testing.T) {

View File

@ -4,14 +4,15 @@ import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// Implements ValidatorSet
var _ sdk.ValidatorSet = Keeper{}
//_______________________________________________________________________
// Validator Set
// iterate through the validator set and perform the provided function
func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) {
func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validator expected.ValidatorI) (stop bool)) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, types.ValidatorsKey)
defer iterator.Close()
@ -27,7 +28,7 @@ func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validato
}
// iterate through the bonded validator set and perform the provided function
func (k Keeper) IterateBondedValidatorsByPower(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) {
func (k Keeper) IterateBondedValidatorsByPower(ctx sdk.Context, fn func(index int64, validator expected.ValidatorI) (stop bool)) {
store := ctx.KVStore(k.storeKey)
maxValidators := k.MaxValidators(ctx)
@ -39,7 +40,7 @@ func (k Keeper) IterateBondedValidatorsByPower(ctx sdk.Context, fn func(index in
address := iterator.Value()
validator := k.mustGetValidator(ctx, address)
if validator.Status == sdk.Bonded {
if validator.IsBonded() {
stop := fn(i, validator) // XXX is this safe will the validator unexposed fields be able to get written to?
if stop {
break
@ -50,7 +51,7 @@ func (k Keeper) IterateBondedValidatorsByPower(ctx sdk.Context, fn func(index in
}
// iterate through the active validator set and perform the provided function
func (k Keeper) IterateLastValidators(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) {
func (k Keeper) IterateLastValidators(ctx sdk.Context, fn func(index int64, validator expected.ValidatorI) (stop bool)) {
iterator := k.LastValidatorsIterator(ctx)
defer iterator.Close()
i := int64(0)
@ -69,8 +70,8 @@ func (k Keeper) IterateLastValidators(ctx sdk.Context, fn func(index int64, vali
}
}
// get the sdk.validator for a particular address
func (k Keeper) Validator(ctx sdk.Context, address sdk.ValAddress) sdk.Validator {
// Validator gets the Validator interface for a particular address
func (k Keeper) Validator(ctx sdk.Context, address sdk.ValAddress) expected.ValidatorI {
val, found := k.GetValidator(ctx, address)
if !found {
return nil
@ -78,8 +79,8 @@ func (k Keeper) Validator(ctx sdk.Context, address sdk.ValAddress) sdk.Validator
return val
}
// get the sdk.validator for a particular pubkey
func (k Keeper) ValidatorByConsAddr(ctx sdk.Context, addr sdk.ConsAddress) sdk.Validator {
// ValidatorByConsAddr gets the validator interface for a particular pubkey
func (k Keeper) ValidatorByConsAddr(ctx sdk.Context, addr sdk.ConsAddress) expected.ValidatorI {
val, found := k.GetValidatorByConsAddr(ctx, addr)
if !found {
return nil
@ -112,17 +113,16 @@ func (k Keeper) InflateSupply(ctx sdk.Context, newTokens sdk.Int) {
k.SetPool(ctx, pool)
}
// Implements DelegationSet
var _ sdk.DelegationSet = Keeper{}
//_______________________________________________________________________
// Delegation Set
// Returns self as it is both a validatorset and delegationset
func (k Keeper) GetValidatorSet() sdk.ValidatorSet {
func (k Keeper) GetValidatorSet() types.ValidatorSet {
return k
}
// get the delegation for a particular set of delegator and validator addresses
func (k Keeper) Delegation(ctx sdk.Context, addrDel sdk.AccAddress, addrVal sdk.ValAddress) sdk.Delegation {
// Delegation get the delegation interface for a particular set of delegator and validator addresses
func (k Keeper) Delegation(ctx sdk.Context, addrDel sdk.AccAddress, addrVal sdk.ValAddress) expected.DelegationI {
bond, ok := k.GetDelegation(ctx, addrDel, addrVal)
if !ok {
return nil
@ -133,7 +133,7 @@ func (k Keeper) Delegation(ctx sdk.Context, addrDel sdk.AccAddress, addrVal sdk.
// iterate through all of the delegations from a delegator
func (k Keeper) IterateDelegations(ctx sdk.Context, delAddr sdk.AccAddress,
fn func(index int64, del sdk.Delegation) (stop bool)) {
fn func(index int64, del expected.DelegationI) (stop bool)) {
store := ctx.KVStore(k.storeKey)
delegatorPrefixKey := types.GetDelegationsKey(delAddr)
@ -151,7 +151,7 @@ func (k Keeper) IterateDelegations(ctx sdk.Context, delAddr sdk.AccAddress,
// return all delegations used during genesis dump
// TODO: remove this func, change all usage for iterate functionality
func (k Keeper) GetAllSDKDelegations(ctx sdk.Context) (delegations []sdk.Delegation) {
func (k Keeper) GetAllSDKDelegations(ctx sdk.Context) (delegations []types.Delegation) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, types.DelegationKey)
defer iterator.Close()

View File

@ -537,7 +537,7 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA
// remove the shares and coins from the validator
validator, amount = k.RemoveValidatorTokensAndShares(ctx, validator, shares)
if validator.DelegatorShares.IsZero() && validator.Status == sdk.Unbonded {
if validator.DelegatorShares.IsZero() && validator.IsUnbonded() {
// if not unbonded, we must instead remove validator in EndBlocker once it finishes its unbonding period
k.RemoveValidator(ctx, validator.OperatorAddress)
}
@ -556,16 +556,17 @@ func (k Keeper) getBeginInfo(
// TODO: When would the validator not be found?
switch {
case !found || validator.Status == sdk.Bonded:
case !found || validator.IsBonded():
// the longest wait - just unbonding period from now
completionTime = ctx.BlockHeader().Time.Add(k.UnbondingTime(ctx))
height = ctx.BlockHeight()
return completionTime, height, false
case validator.Status == sdk.Unbonded:
case validator.IsUnbonded():
return completionTime, height, true
case validator.Status == sdk.Unbonding:
case validator.IsUnbonding():
return validator.UnbondingCompletionTime, validator.UnbondingHeight, false
default:

View File

@ -2,8 +2,12 @@ package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// Implements StakingHooks interface
var _ types.StakingHooks = Keeper{}
// AfterValidatorCreated - call hook if registered
func (k Keeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
if k.hooks != nil {

View File

@ -6,6 +6,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
@ -72,7 +73,7 @@ func SupplyInvariants(k Keeper, f types.FeeCollectionKeeper,
}
return false
})
k.IterateValidators(ctx, func(_ int64, validator sdk.Validator) bool {
k.IterateValidators(ctx, func(_ int64, validator expected.ValidatorI) bool {
switch validator.GetStatus() {
case sdk.Bonded:
bonded = bonded.Add(validator.GetBondedTokens().ToDec())

View File

@ -13,13 +13,19 @@ import (
const aminoCacheSize = 500
// Implements ValidatorSet interface
var _ types.ValidatorSet = Keeper{}
// Implements DelegationSet interface
var _ types.DelegationSet = Keeper{}
// keeper of the staking store
type Keeper struct {
storeKey sdk.StoreKey
storeTKey sdk.StoreKey
cdc *codec.Codec
bankKeeper types.BankKeeper
hooks sdk.StakingHooks
hooks types.StakingHooks
paramstore params.Subspace
validatorCache map[string]cachedValidator
validatorCacheList *list.List
@ -49,7 +55,7 @@ func NewKeeper(cdc *codec.Codec, key, tkey sdk.StoreKey, bk types.BankKeeper,
func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", "x/staking") }
// Set the validator hooks
func (k *Keeper) SetHooks(sh sdk.StakingHooks) *Keeper {
func (k *Keeper) SetHooks(sh types.StakingHooks) *Keeper {
if k.hooks != nil {
panic("cannot set validator hooks twice")
}

View File

@ -48,7 +48,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
}
// should not be slashing an unbonded validator
if validator.Status == sdk.Unbonded {
if validator.IsUnbonded() {
panic(fmt.Sprintf("should not be slashing unbonded validator: %s", validator.GetOperator()))
}

View File

@ -120,21 +120,21 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
// Validator state transitions
func (k Keeper) bondedToUnbonding(ctx sdk.Context, validator types.Validator) types.Validator {
if validator.Status != sdk.Bonded {
if !validator.IsBonded() {
panic(fmt.Sprintf("bad state transition bondedToUnbonding, validator: %v\n", validator))
}
return k.beginUnbondingValidator(ctx, validator)
}
func (k Keeper) unbondingToBonded(ctx sdk.Context, validator types.Validator) types.Validator {
if validator.Status != sdk.Unbonding {
if !validator.IsUnbonding() {
panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator))
}
return k.bondValidator(ctx, validator)
}
func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) types.Validator {
if validator.Status != sdk.Unbonded {
if !validator.IsUnbonded() {
panic(fmt.Sprintf("bad state transition unbondedToBonded, validator: %v\n", validator))
}
return k.bondValidator(ctx, validator)
@ -142,7 +142,7 @@ func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) typ
// switches a validator from unbonding state to unbonded state
func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) types.Validator {
if validator.Status != sdk.Unbonding {
if !validator.IsUnbonding() {
panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator))
}
return k.completeUnbondingValidator(ctx, validator)

View File

@ -187,7 +187,7 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) {
return
}
if validator.Status != sdk.Unbonded {
if !validator.IsUnbonded() {
panic("cannot call RemoveValidator on bonded or unbonding validators")
}
if validator.Tokens.IsPositive() {
@ -253,7 +253,7 @@ func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator {
address := iterator.Value()
validator := k.mustGetValidator(ctx, address)
if validator.Status == sdk.Bonded {
if validator.IsBonded() {
validators[i] = validator
i++
}
@ -432,7 +432,7 @@ func (k Keeper) UnbondAllMatureValidatorQueue(ctx sdk.Context) {
if !found {
panic("validator in the unbonding queue was not found")
}
if val.GetStatus() != sdk.Unbonding {
if !val.IsUnbonding() {
panic("unexpected validator in unbonding queue, status was not unbonding")
}
k.unbondingToUnbonded(ctx, val)

View File

@ -9,6 +9,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// DVPair is struct that just has a delegator-validator pair with no other data.
@ -28,6 +29,9 @@ type DVVTriplet struct {
ValidatorDstAddress sdk.ValAddress
}
// Implements Delegation interface
var _ expected.DelegationI = Delegation{}
// Delegation represents the bond with tokens held by an account. It is
// owned by one delegator, and is associated with the voting power of one
// validator.
@ -75,10 +79,7 @@ func (d Delegation) Equal(d2 Delegation) bool {
d.Shares.Equal(d2.Shares)
}
// ensure fulfills the sdk validator types
var _ sdk.Delegation = Delegation{}
// nolint - for sdk.Delegation
// nolint - for Delegation
func (d Delegation) GetDelegatorAddr() sdk.AccAddress { return d.DelegatorAddress }
func (d Delegation) GetValidatorAddr() sdk.ValAddress { return d.ValidatorAddress }
func (d Delegation) GetShares() sdk.Dec { return d.Shares }

View File

@ -3,6 +3,7 @@ package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// expected coin keeper
@ -22,7 +23,72 @@ type BankKeeper interface {
UndelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error)
}
// expected bank keeper
// AccountKeeper expected Account keeper
type AccountKeeper interface {
IterateAccounts(ctx sdk.Context, process func(auth.Account) (stop bool))
}
// ValidatorSet expected properties for the set of all validators
type ValidatorSet interface {
// iterate through validators by operator address, execute func for each validator
IterateValidators(sdk.Context,
func(index int64, validator expected.ValidatorI) (stop bool))
// iterate through bonded validators by operator address, execute func for each validator
IterateBondedValidatorsByPower(sdk.Context,
func(index int64, validator expected.ValidatorI) (stop bool))
// iterate through the consensus validator set of the last block by operator address, execute func for each validator
IterateLastValidators(sdk.Context,
func(index int64, validator expected.ValidatorI) (stop bool))
Validator(sdk.Context, sdk.ValAddress) expected.ValidatorI // get a particular validator by operator address
ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) expected.ValidatorI // get a particular validator by consensus address
TotalBondedTokens(sdk.Context) sdk.Int // total bonded tokens within the validator set
TotalTokens(sdk.Context) sdk.Int // total token supply
// slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction
Slash(sdk.Context, sdk.ConsAddress, int64, int64, sdk.Dec)
Jail(sdk.Context, sdk.ConsAddress) // jail a validator
Unjail(sdk.Context, sdk.ConsAddress) // unjail a validator
// Delegation allows for getting a particular delegation for a given validator
// and delegator outside the scope of the staking module.
Delegation(sdk.Context, sdk.AccAddress, sdk.ValAddress) expected.DelegationI
// MaxValidators returns the maximum amount of bonded validators
MaxValidators(sdk.Context) uint16
}
// DelegationSet expected properties for the set of all delegations for a particular
type DelegationSet interface {
GetValidatorSet() ValidatorSet // validator set for which delegation set is based upon
// iterate through all delegations from one delegator by validator-AccAddress,
// execute func for each validator
IterateDelegations(ctx sdk.Context, delegator sdk.AccAddress,
fn func(index int64, delegation expected.DelegationI) (stop bool))
}
//_______________________________________________________________________________
// 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.
// StakingHooks event hooks for staking validator object
type StakingHooks interface {
AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) // Must be called when a validator is created
BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) // Must be called when a validator's state changes
AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator is deleted
AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator is bonded
AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator begins unbonding
BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) // Must be called when a delegation is created
BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) // Must be called when a delegation's shares are modified
BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) // Must be called when a delegation is removed
AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress)
BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec)
}

View File

@ -5,9 +5,9 @@ import (
)
// combine multiple staking hooks, all hook functions are run in array sequence
type MultiStakingHooks []sdk.StakingHooks
type MultiStakingHooks []StakingHooks
func NewMultiStakingHooks(hooks ...sdk.StakingHooks) MultiStakingHooks {
func NewMultiStakingHooks(hooks ...StakingHooks) MultiStakingHooks {
return hooks
}

View File

@ -12,6 +12,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/expected"
)
// nolint
@ -23,6 +24,9 @@ const (
MaxDetailsLength = 280
)
// Implements Validator interface
var _ expected.ValidatorI = Validator{}
// Validator defines the total amount of bond shares and their exchange rate to
// coins. Slashing results in a decrease in the exchange rate, allowing correct
// calculation of future undelegations without iterating over delegators.
@ -55,7 +59,7 @@ func (v Validators) String() (out string) {
}
// ToSDKValidators - convenience function convert []Validators to []sdk.Validators
func (v Validators) ToSDKValidators() (validators []sdk.Validator) {
func (v Validators) ToSDKValidators() (validators []expected.ValidatorI) {
for _, val := range v {
validators = append(validators, val)
}
@ -201,6 +205,21 @@ func (v Validator) ConsAddress() sdk.ConsAddress {
return sdk.ConsAddress(v.ConsPubKey.Address())
}
// IsBonded checks if the validator status equals Bonded
func (v Validator) IsBonded() bool {
return v.GetStatus().Equal(sdk.Bonded)
}
// IsUnbonded checks if the validator status equals Unbonded
func (v Validator) IsUnbonded() bool {
return v.GetStatus().Equal(sdk.Unbonded)
}
// IsUnbonding checks if the validator status equals Unbonding
func (v Validator) IsUnbonding() bool {
return v.GetStatus().Equal(sdk.Unbonding)
}
// constant used in flags to indicate that description field should not be updated
const DoNotModifyDesc = "[do-not-modify]"
@ -327,7 +346,7 @@ func (v Validator) RemoveTokens(pool Pool, tokens sdk.Int) (Validator, Pool) {
}
v.Tokens = v.Tokens.Sub(tokens)
// TODO: It is not obvious from the name of the function that this will happen. Either justify or move outside.
if v.Status == sdk.Bonded {
if v.IsBonded() {
pool = pool.bondedTokensToNotBonded(tokens)
}
return v, pool
@ -362,7 +381,7 @@ func (v Validator) AddTokensFromDel(pool Pool, amount sdk.Int) (Validator, Pool,
issuedShares = shares
}
if v.Status == sdk.Bonded {
if v.IsBonded() {
pool = pool.notBondedTokensToBonded(amount)
}
@ -397,7 +416,7 @@ func (v Validator) RemoveDelShares(pool Pool, delShares sdk.Dec) (Validator, Poo
}
v.DelegatorShares = remainingShares
if v.Status == sdk.Bonded {
if v.IsBonded() {
pool = pool.bondedTokensToNotBonded(issuedTokens)
}
@ -449,7 +468,7 @@ func (v Validator) SharesFromTokensTruncated(amt sdk.Int) (sdk.Dec, sdk.Error) {
// get the bonded tokens which the validator holds
func (v Validator) BondedTokens() sdk.Int {
if v.Status == sdk.Bonded {
if v.IsBonded() {
return v.Tokens
}
return sdk.ZeroInt()
@ -458,7 +477,7 @@ func (v Validator) BondedTokens() sdk.Int {
// get the Tendermint Power
// a reduction of 10^6 from validator tokens is applied
func (v Validator) TendermintPower() int64 {
if v.Status == sdk.Bonded {
if v.IsBonded() {
return v.PotentialTendermintPower()
}
return 0
@ -469,10 +488,7 @@ func (v Validator) PotentialTendermintPower() int64 {
return sdk.TokensToTendermintPower(v.Tokens)
}
// ensure fulfills the sdk validator types
var _ sdk.Validator = Validator{}
// nolint - for sdk.Validator
// nolint - for ValidatorI
func (v Validator) IsJailed() bool { return v.Jailed }
func (v Validator) GetMoniker() string { return v.Description.Moniker }
func (v Validator) GetStatus() sdk.BondStatus { return v.Status }