Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(staking): move delegation and validator interfaces to ./types #18198

Merged
merged 11 commits into from
Nov 30, 2023
4 changes: 2 additions & 2 deletions math/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ const MaxBitLen = 256
// Integer errors
var (
// ErrIntOverflow is the error returned when an integer overflow occurs
ErrIntOverflow = errors.New("Integer overflow")
ErrIntOverflow = errors.New("integer overflow")
// ErrDivideByZero is the error returned when a divide by zero occurs
ErrDivideByZero = errors.New("Divide by zero")
ErrDivideByZero = errors.New("divide by zero")
)

func newIntegerFromString(s string) (*big.Int, bool) {
Expand Down
4 changes: 2 additions & 2 deletions simapp/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []
/* Handle fee distribution state. */

// withdraw all validator commission
err := app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
err := app.StakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.ValidatorI) (stop bool) {
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
if err != nil {
panic(err)
Expand Down Expand Up @@ -121,7 +121,7 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []
ctx = ctx.WithBlockHeight(0)

// reinitialize all validators
err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.ValidatorI) (stop bool) {
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
if err != nil {
panic(err)
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/slashing/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ func TestHandleNewValidator(t *testing.T) {

// validator should be bonded still, should not have been jailed or slashed
validator, _ := f.stakingKeeper.GetValidatorByConsAddr(f.ctx, sdk.GetConsAddress(valpubkey))
assert.Equal(t, stakingtypes.Bonded, validator.GetStatus())
assert.Equal(t, sdk.Bonded, validator.GetStatus())
bondPool := f.stakingKeeper.GetBondedPool(f.ctx)
expTokens := f.stakingKeeper.TokensFromConsensusPower(f.ctx, 100)
assert.Assert(t, expTokens.Equal(f.bankKeeper.GetBalance(f.ctx, bondPool.GetAddress(), bondDenom).Amount))
Expand Down Expand Up @@ -335,7 +335,7 @@ func TestHandleAlreadyJailed(t *testing.T) {

// validator should have been jailed and slashed
validator, _ := f.stakingKeeper.GetValidatorByConsAddr(f.ctx, sdk.GetConsAddress(val))
assert.Equal(t, stakingtypes.Unbonding, validator.GetStatus())
assert.Equal(t, sdk.Unbonding, validator.GetStatus())

// validator should have been slashed
resultingTokens := amt.Sub(f.stakingKeeper.TokensFromConsensusPower(f.ctx, 1))
Expand Down
8 changes: 4 additions & 4 deletions tests/integration/staking/keeper/slash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
// power decreased by 1 again, validator is out of stake
// validator should be in unbonding period
validator, _ = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Equal(t, validator.GetStatus(), types.Unbonding)
assert.Equal(t, validator.GetStatus(), sdk.Unbonding)
}

// tests Slash at a previous height with a redelegation
Expand Down Expand Up @@ -514,14 +514,14 @@ func TestSlashWithRedelegation(t *testing.T) {
// read updated validator
// validator decreased to zero power, should be in unbonding period
validator, _ = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Equal(t, validator.GetStatus(), types.Unbonding)
assert.Equal(t, validator.GetStatus(), sdk.Unbonding)

// slash the validator again, by 100%
// no stake remains to be slashed
f.sdkCtx = f.sdkCtx.WithBlockHeight(12)
// validator still in unbonding period
validator, _ = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Equal(t, validator.GetStatus(), types.Unbonding)
assert.Equal(t, validator.GetStatus(), sdk.Unbonding)

_, err = f.stakingKeeper.Slash(f.sdkCtx, consAddr, 10, 10, math.LegacyOneDec())
assert.NilError(t, err)
Expand All @@ -542,7 +542,7 @@ func TestSlashWithRedelegation(t *testing.T) {
// read updated validator
// power still zero, still in unbonding period
validator, _ = f.stakingKeeper.GetValidatorByConsAddr(f.sdkCtx, consAddr)
assert.Equal(t, validator.GetStatus(), types.Unbonding)
assert.Equal(t, validator.GetStatus(), sdk.Unbonding)
}

// tests Slash at a previous height with both an unbonding delegation and a redelegation
Expand Down
10 changes: 5 additions & 5 deletions tests/integration/staking/keeper/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) {
nextCliffVal, _ = nextCliffVal.RemoveDelShares(math.LegacyNewDecFromInt(shares))
_ = keeper.TestingUpdateValidator(f.stakingKeeper, f.sdkCtx, nextCliffVal, true)

expectedValStatus := map[int]types.BondStatus{
9: types.Bonded, 8: types.Bonded, 7: types.Bonded, 5: types.Bonded, 4: types.Bonded,
0: types.Unbonding, 1: types.Unbonding, 2: types.Unbonding, 3: types.Unbonding, 6: types.Unbonding,
expectedValStatus := map[int]sdk.BondStatus{
9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded,
0: sdk.Unbonding, 1: sdk.Unbonding, 2: sdk.Unbonding, 3: sdk.Unbonding, 6: sdk.Unbonding,
}

// require all the validators have their respective statuses
Expand All @@ -121,7 +121,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) {

assert.Equal(
t, status, val.GetStatus(),
fmt.Sprintf("expected validator at index %v to have status: %s", valIdx, status),
fmt.Sprintf("expected validator at index %v to have status: %x", valIdx, status),
)
}
}
Expand Down Expand Up @@ -155,7 +155,7 @@ func TestSlashToZeroPowerRemoved(t *testing.T) {
applyValidatorSetUpdates(t, f.sdkCtx, f.stakingKeeper, -1)
// validator should be unbonding
validator, _ = f.stakingKeeper.GetValidator(f.sdkCtx, addrVals[0])
assert.Equal(t, validator.GetStatus(), types.Unbonding)
assert.Equal(t, validator.GetStatus(), sdk.Unbonding)
}

// test how the validators are sorted, tests GetBondedValidatorsByPower
Expand Down
75 changes: 70 additions & 5 deletions types/staking.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package types

import (
sdkmath "cosmossdk.io/math"
cmtprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto"

"cosmossdk.io/math"

cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
)

// Delay, in blocks, between when validator updates are returned to the
Expand All @@ -21,18 +25,79 @@ var (
DefaultBondDenom = "stake"

// DefaultPowerReduction is the default amount of staking tokens required for 1 unit of consensus-engine power
DefaultPowerReduction = sdkmath.NewIntFromUint64(1000000)
DefaultPowerReduction = math.NewIntFromUint64(1000000)

// PubKeyEd25519Type is ed25519 for type the consensus params validator pub_key_types params
PubKeyEd25519Type = "ed25519"
)

// TokensToConsensusPower - convert input tokens to potential consensus-engine power
func TokensToConsensusPower(tokens, powerReduction sdkmath.Int) int64 {
func TokensToConsensusPower(tokens, powerReduction math.Int) int64 {
return (tokens.Quo(powerReduction)).Int64()
}

// TokensFromConsensusPower - convert input power to tokens
func TokensFromConsensusPower(power int64, powerReduction sdkmath.Int) sdkmath.Int {
return sdkmath.NewInt(power).Mul(powerReduction)
func TokensFromConsensusPower(power int64, powerReduction math.Int) math.Int {
return math.NewInt(power).Mul(powerReduction)
}

// ______________________________________________________________________
// Delegation & Validator Interfaces are moved here to avoid direct dependency on the staking module in expected keeper interfaces

// BondStatus is the status of a validator.
type BondStatus int32

const (
// UNSPECIFIED defines an invalid validator status.
Unspecified BondStatus = 0
// UNBONDED defines a validator that is not bonded.
Unbonded BondStatus = 1
// UNBONDING defines a validator that is unbonding.
Unbonding BondStatus = 2
// BONDED defines a validator that is bonded.
Bonded BondStatus = 3
)

// BondStatus_name is the string representation of BondStatus.
var bondStatus_name = map[int32]string{
0: "BOND_STATUS_UNSPECIFIED",
1: "BOND_STATUS_UNBONDED",
2: "BOND_STATUS_UNBONDING",
3: "BOND_STATUS_BONDED",
}

func (x BondStatus) String() string {
return bondStatus_name[int32(x)]
}

// DelegationI delegation bond for a delegated proof of stake system
type DelegationI interface {
GetDelegatorAddr() string // delegator string for the bond
GetValidatorAddr() string // validator operator address
GetShares() math.LegacyDec // 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() 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() string // operator address to receive/return validators coins
ConsPubKey() (cryptotypes.PubKey, error) // validation consensus pubkey (cryptotypes.PubKey)
TmConsPublicKey() (cmtprotocrypto.PublicKey, error) // validation consensus pubkey (CometBFT)
GetConsAddr() ([]byte, error) // validation consensus address
GetTokens() math.Int // validation tokens
GetBondedTokens() math.Int // validator bonded tokens
GetConsensusPower(math.Int) int64 // validation power in CometBFT
GetCommission() math.LegacyDec // validator commission rate
GetMinSelfDelegation() math.Int // validator minimum self delegation
GetDelegatorShares() math.LegacyDec // total outstanding delegator shares
TokensFromShares(math.LegacyDec) math.LegacyDec // token worth of provided delegator shares
TokensFromSharesTruncated(math.LegacyDec) math.LegacyDec // token worth of provided delegator shares, truncated
TokensFromSharesRoundUp(math.LegacyDec) math.LegacyDec // token worth of provided delegator shares, rounded up
SharesFromTokens(amt math.Int) (math.LegacyDec, error) // shares worth of delegator's bond
SharesFromTokensTruncated(amt math.Int) (math.LegacyDec, error) // truncated shares worth of delegator's bond
}
3 changes: 1 addition & 2 deletions x/distribution/keeper/allocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"cosmossdk.io/core/comet"
"cosmossdk.io/math"
"cosmossdk.io/x/distribution/types"
stakingtypes "cosmossdk.io/x/staking/types"

sdk "github.com/cosmos/cosmos-sdk/types"
)
Expand Down Expand Up @@ -84,7 +83,7 @@ func (k Keeper) AllocateTokens(ctx context.Context, totalPreviousPower int64, bo

// AllocateTokensToValidator allocate tokens to a particular validator,
// splitting according to commission.
func (k Keeper) AllocateTokensToValidator(ctx context.Context, val stakingtypes.ValidatorI, tokens sdk.DecCoins) error {
func (k Keeper) AllocateTokensToValidator(ctx context.Context, val sdk.ValidatorI, tokens sdk.DecCoins) error {
// split tokens between validator and delegators according to commission
commission := tokens.MulDec(val.GetCommission())
shared := tokens.Sub(commission)
Expand Down
7 changes: 3 additions & 4 deletions x/distribution/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"cosmossdk.io/collections"
"cosmossdk.io/math"
"cosmossdk.io/x/distribution/types"
stakingtypes "cosmossdk.io/x/staking/types"

sdk "github.com/cosmos/cosmos-sdk/types"
)
Expand Down Expand Up @@ -47,7 +46,7 @@ func (k Keeper) initializeDelegation(ctx context.Context, val sdk.ValAddress, de
}

// calculate the rewards accrued by a delegation between two periods
func (k Keeper) calculateDelegationRewardsBetween(ctx context.Context, val stakingtypes.ValidatorI,
func (k Keeper) calculateDelegationRewardsBetween(ctx context.Context, val sdk.ValidatorI,
startingPeriod, endingPeriod uint64, stake math.LegacyDec,
) (sdk.DecCoins, error) {
// sanity check
Expand Down Expand Up @@ -86,7 +85,7 @@ func (k Keeper) calculateDelegationRewardsBetween(ctx context.Context, val staki
}

// calculate the total rewards accrued by a delegation
func (k Keeper) CalculateDelegationRewards(ctx context.Context, val stakingtypes.ValidatorI, del stakingtypes.DelegationI, endingPeriod uint64) (rewards sdk.DecCoins, err error) {
func (k Keeper) CalculateDelegationRewards(ctx context.Context, val sdk.ValidatorI, del sdk.DelegationI, endingPeriod uint64) (rewards sdk.DecCoins, err error) {
addrCodec := k.authKeeper.AddressCodec()
delAddr, err := addrCodec.StringToBytes(del.GetDelegatorAddr())
if err != nil {
Expand Down Expand Up @@ -196,7 +195,7 @@ func (k Keeper) CalculateDelegationRewards(ctx context.Context, val stakingtypes
return rewards, nil
}

func (k Keeper) withdrawDelegationRewards(ctx context.Context, val stakingtypes.ValidatorI, del stakingtypes.DelegationI) (sdk.Coins, error) {
func (k Keeper) withdrawDelegationRewards(ctx context.Context, val sdk.ValidatorI, del sdk.DelegationI) (sdk.Coins, error) {
addrCodec := k.authKeeper.AddressCodec()
delAddr, err := addrCodec.StringToBytes(del.GetDelegatorAddr())
if err != nil {
Expand Down
5 changes: 2 additions & 3 deletions x/distribution/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"cosmossdk.io/collections"
"cosmossdk.io/errors"
"cosmossdk.io/x/distribution/types"
stakingtypes "cosmossdk.io/x/staking/types"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
Expand Down Expand Up @@ -267,7 +266,7 @@ func (k Querier) DelegationTotalRewards(ctx context.Context, req *types.QueryDel

err = k.stakingKeeper.IterateDelegations(
ctx, delAdr,
func(_ int64, del stakingtypes.DelegationI) (stop bool) {
func(_ int64, del sdk.DelegationI) (stop bool) {
valAddr, err := k.stakingKeeper.ValidatorAddressCodec().StringToBytes(del.GetValidatorAddr())
if err != nil {
panic(err)
tac0turtle marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -318,7 +317,7 @@ func (k Querier) DelegatorValidators(ctx context.Context, req *types.QueryDelega

err = k.stakingKeeper.IterateDelegations(
ctx, delAdr,
func(_ int64, del stakingtypes.DelegationI) (stop bool) {
func(_ int64, del sdk.DelegationI) (stop bool) {
validators = append(validators, del.GetValidatorAddr())
return false
},
tac0turtle marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
5 changes: 2 additions & 3 deletions x/distribution/keeper/invariants.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"cosmossdk.io/collections"
"cosmossdk.io/x/distribution/types"
stakingtypes "cosmossdk.io/x/staking/types"

sdk "github.com/cosmos/cosmos-sdk/types"
)
Expand Down Expand Up @@ -90,7 +89,7 @@ func CanWithdrawInvariant(k Keeper) sdk.Invariant {
}

// iterate over all validators
err = k.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
err = k.stakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.ValidatorI) (stop bool) {
valBz, err1 := k.stakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
if err != nil {
panic(err1)
Expand Down Expand Up @@ -132,7 +131,7 @@ func CanWithdrawInvariant(k Keeper) sdk.Invariant {
func ReferenceCountInvariant(k Keeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
valCount := uint64(0)
err := k.stakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
err := k.stakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.ValidatorI) (stop bool) {
valCount++
return false
})
Expand Down
5 changes: 2 additions & 3 deletions x/distribution/keeper/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ import (
"cosmossdk.io/collections"
"cosmossdk.io/math"
"cosmossdk.io/x/distribution/types"
stakingtypes "cosmossdk.io/x/staking/types"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// initialize rewards for a new validator
func (k Keeper) initializeValidator(ctx context.Context, val stakingtypes.ValidatorI) error {
func (k Keeper) initializeValidator(ctx context.Context, val sdk.ValidatorI) error {
valBz, err := k.stakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
if err != nil {
return err
Expand Down Expand Up @@ -44,7 +43,7 @@ func (k Keeper) initializeValidator(ctx context.Context, val stakingtypes.Valida
}

// increment validator period, returning the period just ended
func (k Keeper) IncrementValidatorPeriod(ctx context.Context, val stakingtypes.ValidatorI) (uint64, error) {
func (k Keeper) IncrementValidatorPeriod(ctx context.Context, val sdk.ValidatorI) (uint64, error) {
valBz, err := k.stakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
if err != nil {
return 0, err
Expand Down
16 changes: 8 additions & 8 deletions x/distribution/testutil/expected_keepers_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading