Skip to content

Commit

Permalink
Merge PR cosmos#4417: cleanup staking references from types pkg
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
fedekunze authored and jackzampolin committed Jun 4, 2019
1 parent fe695b8 commit d322e23
Show file tree
Hide file tree
Showing 36 changed files with 384 additions and 267 deletions.
2 changes: 2 additions & 0 deletions .pending/improvements/sdk/3928-remove-types-staking
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#3928 remove staking references from types package
#1528 define local module interfaces instead of /types
4 changes: 2 additions & 2 deletions docs/spec/staking/04_end_block.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
5 changes: 3 additions & 2 deletions simapp/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
})
Expand All @@ -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())
Expand Down
156 changes: 26 additions & 130 deletions types/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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))

Expand All @@ -58,112 +31,35 @@ func TokensFromTendermintPower(power int64) Int {
return NewInt(power).Mul(PowerReduction)
}

// nolint
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(),
}
}

// 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
}

//_______________________________________________________________________________
// BondStatus is the status of a validator
type BondStatus byte

// 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
}
// staking constants
const (
Unbonded BondStatus = 0x00
Unbonding BondStatus = 0x01
Bonded BondStatus = 0x02

// properties for the set of all delegations for a particular
type DelegationSet interface {
GetValidatorSet() ValidatorSet // validator set for which delegation set is based upon
BondStatusUnbonded = "Unbonded"
BondStatusUnbonding = "Unbonding"
BondStatusBonded = "Bonded"
)

// 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))
// Equal compares two BondStatus instances
func (b BondStatus) Equal(b2 BondStatus) bool {
return byte(b) == byte(b2)
}

//_______________________________________________________________________________
// 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)
// 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")
}
}
5 changes: 3 additions & 2 deletions x/distribution/keeper/allocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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())
Expand Down
7 changes: 4 additions & 3 deletions x/distribution/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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())

Expand Down Expand Up @@ -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)
Expand Down
23 changes: 13 additions & 10 deletions x/distribution/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)

// Wrapper struct
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} }
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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) {}
5 changes: 3 additions & 2 deletions x/distribution/keeper/invariants.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()]
Expand Down Expand Up @@ -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
})
Expand Down
Loading

0 comments on commit d322e23

Please sign in to comment.