Skip to content

Commit

Permalink
Merge PR #4524: Staking ValidatorPowerRank to use "Potential Consensu…
Browse files Browse the repository at this point in the history
…s Power"
  • Loading branch information
rigelrozanski authored and alexanderbez committed Jun 12, 2019
1 parent b096357 commit 8c89023
Show file tree
Hide file tree
Showing 37 changed files with 546 additions and 546 deletions.
1 change: 1 addition & 0 deletions .pending/breaking/sdk/3985-ValidatorPowerR
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#3985 `ValidatorPowerRank` uses potential consensus power instead of tendermint power
47 changes: 24 additions & 23 deletions docs/spec/staking/01_state.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ records within a block.

- Validators: `0x21 | OperatorAddr -> amino(validator)`
- ValidatorsByConsAddr: `0x22 | ConsAddr -> OperatorAddr`
- ValidatorsByPower: `0x23 | BigEndian(Tokens) | OperatorAddr -> OperatorAddr`
- LastValidatorsPower: `0x11 OperatorAddr -> amino(Tokens)
- ValidatorsByPower: `0x23 | BigEndian(ConsensusPower) | OperatorAddr -> OperatorAddr`
- LastValidatorsPower: `0x11 OperatorAddr -> amino(ConsensusPower)

`Validators` is the primary index - it ensures that each operator can have only one
associated validator, where the public key of that validator can change in the
Expand All @@ -66,8 +66,9 @@ map is needed to find the operator. Note that the `ConsAddr` corresponds to the
address which can be derived from the validator's `ConsPubKey`.

`ValidatorsByPower` is an additional index that provides a sorted list o
potential validators to quickly determine the current active set. Note
that all validators where `Jailed` is true are not stored within this index.
potential validators to quickly determine the current active set. Here
ConsensusPower is validator.Tokens/10^6. Note that all validators where
`Jailed` is true are not stored within this index.

`LastValidatorsPower` is a special index that provides a historical list of the
last-block's bonded validators. This index remains constant during a block but
Expand All @@ -78,28 +79,28 @@ Each validator's state is stored in a `Validator` struct:

```golang
type Validator struct {
OperatorAddr sdk.ValAddress // address of the validator's operator; bech encoded in JSON
ConsPubKey crypto.PubKey // Tendermint consensus pubkey of validator
Jailed bool // has the validator been jailed?

Status sdk.BondStatus // validator status (bonded/unbonding/unbonded)
Tokens sdk.Int // delegated tokens (incl. self-delegation)
DelegatorShares sdk.Dec // total shares issued to a validator's delegators

Description Description // description terms for the validator

// Needed for ordering vals in the by-power key
UnbondingHeight int64 // if unbonding, height at which this validator has begun unbonding
UnbondingMinTime time.Time // if unbonding, min time for the validator to complete unbonding

Commission Commission // info about the validator's commission
OperatorAddress sdk.ValAddress // address of the validator's operator; bech encoded in JSON
ConsPubKey crypto.PubKey // the consensus public key of the validator; bech encoded in JSON
Jailed bool // has the validator been jailed from bonded status?
Status sdk.BondStatus // validator status (bonded/unbonding/unbonded)
Tokens sdk.Int // delegated tokens (incl. self-delegation)
DelegatorShares sdk.Dec // total shares issued to a validator's delegators
Description Description // description terms for the validator
UnbondingHeight int64 // if unbonding, height at which this validator has begun unbonding
UnbondingCompletionTime time.Time // if unbonding, min time for the validator to complete unbonding
Commission Commission // commission parameters
MinSelfDelegation sdk.Int // validator's self declared minimum self delegation
}

type Commission struct {
Rate sdk.Dec // the commission rate charged to delegators
MaxRate sdk.Dec // maximum commission rate which this validator can ever charge
MaxChangeRate sdk.Dec // maximum daily increase of the validator commission
UpdateTime time.Time // the last time the commission rate was changed
CommissionRates
UpdateTime time.Time // the last time the commission rate was changed
}

CommissionRates struct {
Rate sdk.Dec // the commission rate charged to delegators, as a fraction
MaxRate sdk.Dec // maximum commission rate which validator can ever charge, as a fraction
MaxChangeRate sdk.Dec // maximum daily increase of the validator commission, as a fraction
}

type Description struct {
Expand Down
11 changes: 11 additions & 0 deletions types/bytes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package types

// copy bytes
func CopyBytes(bz []byte) (ret []byte) {
if bz == nil {
return nil
}
ret = make([]byte, len(bz))
copy(ret, bz)
return ret
}
24 changes: 14 additions & 10 deletions types/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,28 @@ const (
// default bond denomination
DefaultBondDenom = "stake"

// Delay, in blocks, between when validator updates are returned to Tendermint and when they are applied.
// For example, if this is 0, the validator set at the end of a block will sign the next block, or
// if this is 1, the validator set at the end of a block will sign the block after the next.
// Constant as this should not change without a hard fork.
// TODO: Link to some Tendermint docs, this is very unobvious.
// Delay, in blocks, between when validator updates are returned to the
// consensus-engine and when they are applied. For example, if
// ValidatorUpdateDelay is set to X, and if a validator set update is
// returned with new validators at the end of block 10, then the new
// validators are expected to sign blocks beginning at block 11+X.
//
// This value is constant as this should not change without a hard fork.
// For Tendermint this should be set to 1 block, for more details see:
// https://tendermint.com/docs/spec/abci/apps.html#endblock
ValidatorUpdateDelay int64 = 1
)

// PowerReduction is the amount of staking tokens required for 1 unit of Tendermint power
// PowerReduction is the amount of staking tokens required for 1 unit of consensus-engine power
var PowerReduction = NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(6), nil))

// TokensToTendermintPower - convert input tokens to potential tendermint power
func TokensToTendermintPower(tokens Int) int64 {
// TokensToConsensusPower - convert input tokens to potential consensus-engine power
func TokensToConsensusPower(tokens Int) int64 {
return (tokens.Quo(PowerReduction)).Int64()
}

// TokensFromTendermintPower - convert input power to tokens
func TokensFromTendermintPower(power int64) Int {
// TokensFromConsensusPower - convert input power to tokens
func TokensFromConsensusPower(power int64) Int {
return NewInt(power).Mul(PowerReduction)
}

Expand Down
24 changes: 12 additions & 12 deletions x/distribution/keeper/delegation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func TestCalculateRewardsAfterSlash(t *testing.T) {
// create validator with 50% commission
commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0))
valPower := int64(100)
valTokens := sdk.TokensFromTendermintPower(valPower)
valTokens := sdk.TokensFromConsensusPower(valPower)
msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1,
sdk.NewCoin(sdk.DefaultBondDenom, valTokens), staking.Description{}, commission, sdk.OneInt())
got := sh(ctx, msg)
Expand Down Expand Up @@ -107,7 +107,7 @@ func TestCalculateRewardsAfterSlash(t *testing.T) {
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)

// allocate some rewards
initial := sdk.TokensFromTendermintPower(10)
initial := sdk.TokensFromConsensusPower(10)
tokens := sdk.DecCoins{{sdk.DefaultBondDenom, initial.ToDec()}}
k.AllocateTokensToValidator(ctx, val, tokens)

Expand All @@ -131,7 +131,7 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) {

// create validator with 50% commission
power := int64(100)
valTokens := sdk.TokensFromTendermintPower(power)
valTokens := sdk.TokensFromConsensusPower(power)
commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0))
msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1,
sdk.NewCoin(sdk.DefaultBondDenom, valTokens), staking.Description{}, commission, sdk.OneInt())
Expand Down Expand Up @@ -169,7 +169,7 @@ func TestCalculateRewardsAfterManySlashes(t *testing.T) {
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)

// allocate some rewards
initial := sdk.TokensFromTendermintPower(10)
initial := sdk.TokensFromConsensusPower(10)
tokens := sdk.DecCoins{{sdk.DefaultBondDenom, initial.ToDec()}}
k.AllocateTokensToValidator(ctx, val, tokens)

Expand Down Expand Up @@ -262,13 +262,13 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) {

func TestWithdrawDelegationRewardsBasic(t *testing.T) {
balancePower := int64(1000)
balanceTokens := sdk.TokensFromTendermintPower(balancePower)
balanceTokens := sdk.TokensFromConsensusPower(balancePower)
ctx, ak, k, sk, _ := CreateTestInputDefault(t, false, balancePower)
sh := staking.NewHandler(sk)

// create validator with 50% commission
power := int64(100)
valTokens := sdk.TokensFromTendermintPower(power)
valTokens := sdk.TokensFromConsensusPower(power)
commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0))
msg := staking.NewMsgCreateValidator(
valOpAddr1, valConsPk1,
Expand All @@ -294,7 +294,7 @@ func TestWithdrawDelegationRewardsBasic(t *testing.T) {
val := sk.Validator(ctx, valOpAddr1)

// allocate some rewards
initial := sdk.TokensFromTendermintPower(10)
initial := sdk.TokensFromConsensusPower(10)
tokens := sdk.DecCoins{sdk.NewDecCoin(sdk.DefaultBondDenom, initial)}

k.AllocateTokensToValidator(ctx, val, tokens)
Expand Down Expand Up @@ -334,7 +334,7 @@ func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) {

// create validator with 50% commission
power := int64(100)
valTokens := sdk.TokensFromTendermintPower(power)
valTokens := sdk.TokensFromConsensusPower(power)
commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0))
msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1,
sdk.NewCoin(sdk.DefaultBondDenom, valTokens), staking.Description{}, commission, sdk.OneInt())
Expand Down Expand Up @@ -363,7 +363,7 @@ func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) {
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)

// allocate some rewards
initial := sdk.TokensFromTendermintPower(10).ToDec()
initial := sdk.TokensFromConsensusPower(10).ToDec()
tokens := sdk.DecCoins{{sdk.DefaultBondDenom, initial}}
k.AllocateTokensToValidator(ctx, val, tokens)

Expand Down Expand Up @@ -402,7 +402,7 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) {
// create validator with 50% commission
commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0))
power := int64(100)
valTokens := sdk.TokensFromTendermintPower(power)
valTokens := sdk.TokensFromConsensusPower(power)
msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1,
sdk.NewCoin(sdk.DefaultBondDenom, valTokens), staking.Description{}, commission, sdk.OneInt())
require.True(t, sh(ctx, msg).IsOK())
Expand All @@ -418,7 +418,7 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) {
del1 := sk.Delegation(ctx, sdk.AccAddress(valOpAddr1), valOpAddr1)

// allocate some rewards
initial := sdk.TokensFromTendermintPower(30).ToDec()
initial := sdk.TokensFromConsensusPower(30).ToDec()
tokens := sdk.DecCoins{{sdk.DefaultBondDenom, initial}}
k.AllocateTokensToValidator(ctx, val, tokens)

Expand All @@ -428,7 +428,7 @@ func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) {
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)

// second delegation
delTokens := sdk.TokensFromTendermintPower(100)
delTokens := sdk.TokensFromConsensusPower(100)
msg2 := staking.NewMsgDelegate(sdk.AccAddress(valOpAddr2), valOpAddr1,
sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
require.True(t, sh(ctx, msg2).IsOK())
Expand Down
4 changes: 2 additions & 2 deletions x/distribution/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ func TestWithdrawValidatorCommission(t *testing.T) {

// check initial balance
balance := ak.GetAccount(ctx, sdk.AccAddress(valOpAddr3)).GetCoins()
expTokens := sdk.TokensFromTendermintPower(1000)
expTokens := sdk.TokensFromConsensusPower(1000)
require.Equal(t, sdk.Coins{
sdk.NewCoin("stake", sdk.TokensFromTendermintPower(1000)),
sdk.NewCoin("stake", sdk.TokensFromConsensusPower(1000)),
}, balance)

// set outstanding rewards
Expand Down
2 changes: 1 addition & 1 deletion x/distribution/keeper/test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func CreateTestInputAdvanced(t *testing.T, isCheckTx bool, initPower int64,
communityTax sdk.Dec) (sdk.Context, auth.AccountKeeper, bank.Keeper,
Keeper, staking.Keeper, DummyFeeCollectionKeeper, params.Keeper) {

initCoins := sdk.TokensFromTendermintPower(initPower)
initCoins := sdk.TokensFromConsensusPower(initPower)

keyDistr := sdk.NewKVStoreKey(types.StoreKey)
keyStaking := sdk.NewKVStoreKey(staking.StoreKey)
Expand Down
2 changes: 1 addition & 1 deletion x/genutil/gentx.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

var (
defaultTokens = sdk.TokensFromTendermintPower(100)
defaultTokens = sdk.TokensFromConsensusPower(100)
defaultAmount = defaultTokens.String() + sdk.DefaultBondDenom
defaultCommissionRate = "0.1"
defaultCommissionMaxRate = "0.2"
Expand Down
6 changes: 3 additions & 3 deletions x/gov/endblocker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func TestTickPassedVotingPeriod(t *testing.T) {
require.False(t, activeQueue.Valid())
activeQueue.Close()

proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(5))}
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(5))}
newProposalMsg := NewMsgSubmitProposal(testProposal(), proposalCoins, input.addrs[0])

res := govHandler(ctx, newProposalMsg)
Expand Down Expand Up @@ -264,7 +264,7 @@ func TestProposalPassedEndblocker(t *testing.T) {
proposal, err := input.keeper.SubmitProposal(ctx, testProposal())
require.NoError(t, err)

proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(10))}
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10))}
newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins)
res := handler(ctx, newDepositMsg)
require.True(t, res.IsOK())
Expand Down Expand Up @@ -306,7 +306,7 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) {
proposal, err := input.keeper.SubmitProposal(ctx, testProposal())
require.NoError(t, err)

proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(10)))
proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)))
newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins)
res := handler(ctx, newDepositMsg)
require.True(t, res.IsOK())
Expand Down
2 changes: 1 addition & 1 deletion x/gov/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func NewGenesisState(startingProposalID uint64, dp DepositParams, vp VotingParam

// get raw genesis raw message for testing
func DefaultGenesisState() GenesisState {
minDepositTokens := sdk.TokensFromTendermintPower(10)
minDepositTokens := sdk.TokensFromConsensusPower(10)
return GenesisState{
StartingProposalID: 1,
DepositParams: DepositParams{
Expand Down
6 changes: 3 additions & 3 deletions x/gov/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ func TestDeposits(t *testing.T) {
require.NoError(t, err)
proposalID := proposal.ProposalID

fourStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(4)))
fiveStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(5)))
fourStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(4)))
fiveStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(5)))

addr0Initial := input.keeper.ck.GetCoins(ctx, input.addrs[0])
addr1Initial := input.keeper.ck.GetCoins(ctx, input.addrs[1])

expTokens := sdk.TokensFromTendermintPower(42)
expTokens := sdk.TokensFromConsensusPower(42)
require.Equal(t, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, expTokens)), addr0Initial)
require.True(t, proposal.TotalDeposit.IsEqual(sdk.NewCoins()))

Expand Down
16 changes: 8 additions & 8 deletions x/gov/tally_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func TestTallyDelgatorOverride(t *testing.T) {
createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 6, 7})
staking.EndBlocker(ctx, input.sk)

delTokens := sdk.TokensFromTendermintPower(30)
delTokens := sdk.TokensFromConsensusPower(30)
delegator1Msg := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
stakingHandler(ctx, delegator1Msg)

Expand Down Expand Up @@ -416,7 +416,7 @@ func TestTallyDelgatorInherit(t *testing.T) {
createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 6, 7})
staking.EndBlocker(ctx, input.sk)

delTokens := sdk.TokensFromTendermintPower(30)
delTokens := sdk.TokensFromConsensusPower(30)
delegator1Msg := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
stakingHandler(ctx, delegator1Msg)

Expand Down Expand Up @@ -460,7 +460,7 @@ func TestTallyDelgatorMultipleOverride(t *testing.T) {
createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 6, 7})
staking.EndBlocker(ctx, input.sk)

delTokens := sdk.TokensFromTendermintPower(10)
delTokens := sdk.TokensFromConsensusPower(10)
delegator1Msg := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
stakingHandler(ctx, delegator1Msg)
delegator1Msg2 := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[1]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
Expand Down Expand Up @@ -500,25 +500,25 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) {
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
stakingHandler := staking.NewHandler(input.sk)

valTokens1 := sdk.TokensFromTendermintPower(25)
valTokens1 := sdk.TokensFromConsensusPower(25)
val1CreateMsg := staking.NewMsgCreateValidator(
sdk.ValAddress(input.addrs[0]), ed25519.GenPrivKey().PubKey(), sdk.NewCoin(sdk.DefaultBondDenom, valTokens1), testDescription, testCommissionRates, sdk.OneInt(),
)
stakingHandler(ctx, val1CreateMsg)

valTokens2 := sdk.TokensFromTendermintPower(6)
valTokens2 := sdk.TokensFromConsensusPower(6)
val2CreateMsg := staking.NewMsgCreateValidator(
sdk.ValAddress(input.addrs[1]), ed25519.GenPrivKey().PubKey(), sdk.NewCoin(sdk.DefaultBondDenom, valTokens2), testDescription, testCommissionRates, sdk.OneInt(),
)
stakingHandler(ctx, val2CreateMsg)

valTokens3 := sdk.TokensFromTendermintPower(7)
valTokens3 := sdk.TokensFromConsensusPower(7)
val3CreateMsg := staking.NewMsgCreateValidator(
sdk.ValAddress(input.addrs[2]), ed25519.GenPrivKey().PubKey(), sdk.NewCoin(sdk.DefaultBondDenom, valTokens3), testDescription, testCommissionRates, sdk.OneInt(),
)
stakingHandler(ctx, val3CreateMsg)

delTokens := sdk.TokensFromTendermintPower(10)
delTokens := sdk.TokensFromConsensusPower(10)
delegator1Msg := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
stakingHandler(ctx, delegator1Msg)

Expand Down Expand Up @@ -567,7 +567,7 @@ func TestTallyJailedValidator(t *testing.T) {
createValidators(t, stakingHandler, ctx, valAddrs, []int64{25, 6, 7})
staking.EndBlocker(ctx, input.sk)

delTokens := sdk.TokensFromTendermintPower(10)
delTokens := sdk.TokensFromConsensusPower(10)
delegator1Msg := staking.NewMsgDelegate(input.addrs[3], sdk.ValAddress(input.addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
stakingHandler(ctx, delegator1Msg)

Expand Down
Loading

0 comments on commit 8c89023

Please sign in to comment.