Merge branch 'cwgoes/check-supply-in-simulation' of github.com:cosmos/cosmos-sdk into cwgoes/check-supply-in-simulation

This commit is contained in:
Christopher Goes 2018-10-23 02:39:25 +02:00
commit 7f43860ca9
37 changed files with 305 additions and 152 deletions

View File

@ -3,6 +3,10 @@ package app
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"os"
"sort"
bam "github.com/cosmos/cosmos-sdk/baseapp" bam "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
@ -19,9 +23,6 @@ import (
dbm "github.com/tendermint/tendermint/libs/db" dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
"io"
"os"
"sort"
) )
const ( const (
@ -334,8 +335,8 @@ var _ sdk.StakingHooks = Hooks{}
func (h Hooks) OnValidatorCreated(ctx sdk.Context, addr sdk.ValAddress) { func (h Hooks) OnValidatorCreated(ctx sdk.Context, addr sdk.ValAddress) {
h.dh.OnValidatorCreated(ctx, addr) h.dh.OnValidatorCreated(ctx, addr)
} }
func (h Hooks) OnValidatorCommissionChange(ctx sdk.Context, addr sdk.ValAddress) { func (h Hooks) OnValidatorModified(ctx sdk.Context, addr sdk.ValAddress) {
h.dh.OnValidatorCommissionChange(ctx, addr) h.dh.OnValidatorModified(ctx, addr)
} }
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, addr sdk.ValAddress) { func (h Hooks) OnValidatorRemoved(ctx sdk.Context, addr sdk.ValAddress) {
h.dh.OnValidatorRemoved(ctx, addr) h.dh.OnValidatorRemoved(ctx, addr)
@ -344,6 +345,7 @@ func (h Hooks) OnValidatorBonded(ctx sdk.Context, addr sdk.ConsAddress) {
h.sh.OnValidatorBonded(ctx, addr) h.sh.OnValidatorBonded(ctx, addr)
} }
func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, addr sdk.ConsAddress, operator sdk.ValAddress) { func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, addr sdk.ConsAddress, operator sdk.ValAddress) {
h.dh.OnValidatorBeginUnbonding(ctx, addr, operator)
h.sh.OnValidatorBeginUnbonding(ctx, addr, operator) h.sh.OnValidatorBeginUnbonding(ctx, addr, operator)
} }
func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {

View File

@ -5,9 +5,9 @@ The staking module allow for the following hooks to be registered with staking e
``` golang ``` golang
// event hooks for staking validator object // event hooks for staking validator object
type StakingHooks interface { type StakingHooks interface {
OnValidatorCreated(ctx Context, address ValAddress) // called when a validator is created OnValidatorCreated(ctx Context, address ValAddress) // Must be called when a validator is created
OnValidatorCommissionChange(ctx Context, address ValAddress) // called when a validator's commission is modified OnValidatorModified(ctx Context, address ValAddress) // Must be called when a validator's state changes
OnValidatorRemoved(ctx Context, address ValAddress) // called when a validator is deleted OnValidatorRemoved(ctx Context, address ValAddress) // Must be called when a validator is deleted
OnValidatorBonded(ctx Context, address ConsAddress) // called when a validator is bonded OnValidatorBonded(ctx Context, address ConsAddress) // called when a validator is bonded
OnValidatorBeginUnbonding(ctx Context, address ConsAddress, operator ValAddress) // called when a validator begins unbonding OnValidatorBeginUnbonding(ctx Context, address ConsAddress, operator ValAddress) // called when a validator begins unbonding

View File

@ -247,6 +247,11 @@ func (d Dec) QuoInt(i Int) Dec {
return Dec{mul} return Dec{mul}
} }
// is integer, e.g. decimals are zero.
func (d Dec) IsInteger() bool {
return new(big.Int).Rem(d.Int, precisionReuse).Sign() == 0
}
func (d Dec) String() string { func (d Dec) String() string {
str := d.ToLeftPaddedWithDecimals(Precision) str := d.ToLeftPaddedWithDecimals(Precision)
placement := len(str) - Precision placement := len(str) - Precision

View File

@ -85,8 +85,8 @@ type ValidatorSet interface {
// delegation bond for a delegated proof of stake system // delegation bond for a delegated proof of stake system
type Delegation interface { type Delegation interface {
GetDelegator() AccAddress // delegator AccAddress for the bond GetDelegatorAddr() AccAddress // delegator AccAddress for the bond
GetValidator() ValAddress // validator operator address GetValidatorAddr() ValAddress // validator operator address
GetShares() Dec // amount of validator's shares held in this delegation GetShares() Dec // amount of validator's shares held in this delegation
} }
@ -112,7 +112,7 @@ type DelegationSet interface {
// event hooks for staking validator object // event hooks for staking validator object
type StakingHooks interface { type StakingHooks interface {
OnValidatorCreated(ctx Context, address ValAddress) // Must be called when a validator is created OnValidatorCreated(ctx Context, address ValAddress) // Must be called when a validator is created
OnValidatorCommissionChange(ctx Context, address ValAddress) // Must be called when a validator's commission is modified OnValidatorModified(ctx Context, address ValAddress) // Must be called when a validator's state changes
OnValidatorRemoved(ctx Context, address ValAddress) // Must be called when a validator is deleted OnValidatorRemoved(ctx Context, address ValAddress) // Must be called when a validator is deleted
OnValidatorBonded(ctx Context, address ConsAddress) // Must be called when a validator is bonded OnValidatorBonded(ctx Context, address ConsAddress) // Must be called when a validator is bonded

View File

@ -69,24 +69,28 @@ func (k Keeper) RemoveDelegatorWithdrawAddr(ctx sdk.Context, delAddr, withdrawAd
//___________________________________________________________________________________________ //___________________________________________________________________________________________
// withdraw all the rewards for a single delegation // Withdraw all the rewards for a single delegation.
// NOTE: This gets called "onDelegationSharesModified",
// meaning any changes to bonded coins.
func (k Keeper) WithdrawDelegationReward(ctx sdk.Context, delegatorAddr sdk.AccAddress, func (k Keeper) WithdrawDelegationReward(ctx sdk.Context, delegatorAddr sdk.AccAddress,
validatorAddr sdk.ValAddress) sdk.Error { valAddr sdk.ValAddress) sdk.Error {
if !k.HasDelegationDistInfo(ctx, delegatorAddr, validatorAddr) { if !k.HasDelegationDistInfo(ctx, delegatorAddr, valAddr) {
return types.ErrNoDelegationDistInfo(k.codespace) return types.ErrNoDelegationDistInfo(k.codespace)
} }
// TODO: Reconcile with duplicate code in getDelegatorRewardsAll.
height := ctx.BlockHeight() height := ctx.BlockHeight()
bondedTokens := k.stakeKeeper.TotalPower(ctx) lastTotalPower := k.stakeKeeper.GetLastTotalPower(ctx)
lastValPower := k.stakeKeeper.GetLastValidatorPower(ctx, valAddr)
feePool := k.GetFeePool(ctx) feePool := k.GetFeePool(ctx)
delInfo := k.GetDelegationDistInfo(ctx, delegatorAddr, validatorAddr) delInfo := k.GetDelegationDistInfo(ctx, delegatorAddr, valAddr)
valInfo := k.GetValidatorDistInfo(ctx, validatorAddr) valInfo := k.GetValidatorDistInfo(ctx, valAddr)
validator := k.stakeKeeper.Validator(ctx, validatorAddr) validator := k.stakeKeeper.Validator(ctx, valAddr)
delegation := k.stakeKeeper.Delegation(ctx, delegatorAddr, validatorAddr) delegation := k.stakeKeeper.Delegation(ctx, delegatorAddr, valAddr)
delInfo, valInfo, feePool, withdraw := delInfo.WithdrawRewards(feePool, valInfo, height, bondedTokens, delInfo, valInfo, feePool, withdraw := delInfo.WithdrawRewards(feePool, valInfo, height, lastTotalPower,
validator.GetPower(), validator.GetDelegatorShares(), delegation.GetShares(), validator.GetCommission()) lastValPower, validator.GetDelegatorShares(), delegation.GetShares(), validator.GetCommission())
k.SetValidatorDistInfo(ctx, valInfo) k.SetValidatorDistInfo(ctx, valInfo)
k.SetDelegationDistInfo(ctx, delInfo) k.SetDelegationDistInfo(ctx, delInfo)
@ -122,19 +126,21 @@ func (k Keeper) WithdrawDelegationRewardsAll(ctx sdk.Context, delegatorAddr sdk.
func (k Keeper) getDelegatorRewardsAll(ctx sdk.Context, delAddr sdk.AccAddress, height int64) types.DecCoins { func (k Keeper) getDelegatorRewardsAll(ctx sdk.Context, delAddr sdk.AccAddress, height int64) types.DecCoins {
withdraw := types.DecCoins{} withdraw := types.DecCoins{}
bondedTokens := k.stakeKeeper.TotalPower(ctx) lastTotalPower := k.stakeKeeper.GetLastTotalPower(ctx)
// iterate over all the delegations // iterate over all the delegations
// TODO: Reconcile with duplicate code in WithdrawDelegationReward.
operationAtDelegation := func(_ int64, del sdk.Delegation) (stop bool) { operationAtDelegation := func(_ int64, del sdk.Delegation) (stop bool) {
feePool := k.GetFeePool(ctx) feePool := k.GetFeePool(ctx)
valAddr := del.GetValidator() valAddr := del.GetValidatorAddr()
lastValPower := k.stakeKeeper.GetLastValidatorPower(ctx, valAddr)
delInfo := k.GetDelegationDistInfo(ctx, delAddr, valAddr) delInfo := k.GetDelegationDistInfo(ctx, delAddr, valAddr)
valInfo := k.GetValidatorDistInfo(ctx, valAddr) valInfo := k.GetValidatorDistInfo(ctx, valAddr)
validator := k.stakeKeeper.Validator(ctx, valAddr) validator := k.stakeKeeper.Validator(ctx, valAddr)
delegation := k.stakeKeeper.Delegation(ctx, delAddr, valAddr) delegation := k.stakeKeeper.Delegation(ctx, delAddr, valAddr)
delInfo, valInfo, feePool, diWithdraw := delInfo.WithdrawRewards(feePool, valInfo, height, bondedTokens, delInfo, valInfo, feePool, diWithdraw := delInfo.WithdrawRewards(feePool, valInfo, height, lastTotalPower,
validator.GetPower(), validator.GetDelegatorShares(), delegation.GetShares(), validator.GetCommission()) lastValPower, validator.GetDelegatorShares(), delegation.GetShares(), validator.GetCommission())
withdraw = withdraw.Plus(diWithdraw) withdraw = withdraw.Plus(diWithdraw)
k.SetFeePool(ctx, feePool) k.SetFeePool(ctx, feePool)
k.SetValidatorDistInfo(ctx, valInfo) k.SetValidatorDistInfo(ctx, valInfo)

View File

@ -34,6 +34,8 @@ func TestWithdrawDelegationRewardBasic(t *testing.T) {
// withdraw delegation // withdraw delegation
ctx = ctx.WithBlockHeight(1) ctx = ctx.WithBlockHeight(1)
sk.SetLastTotalPower(ctx, sdk.NewDec(10))
sk.SetLastValidatorPower(ctx, valOpAddr1, sdk.NewDec(10))
keeper.WithdrawDelegationReward(ctx, delAddr1, valOpAddr1) keeper.WithdrawDelegationReward(ctx, delAddr1, valOpAddr1)
amt = accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom) amt = accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
@ -204,8 +206,6 @@ func TestWithdrawDelegationRewardsAll(t *testing.T) {
got = stakeHandler(ctx, msgCreateValidator) got = stakeHandler(ctx, msgCreateValidator)
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got) require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
// delegate to all the validators // delegate to all the validators
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10) msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10)
require.True(t, stakeHandler(ctx, msgDelegate).IsOK()) require.True(t, stakeHandler(ctx, msgDelegate).IsOK())
@ -214,6 +214,9 @@ func TestWithdrawDelegationRewardsAll(t *testing.T) {
msgDelegate = stake.NewTestMsgDelegate(delAddr1, valOpAddr3, 30) msgDelegate = stake.NewTestMsgDelegate(delAddr1, valOpAddr3, 30)
require.True(t, stakeHandler(ctx, msgDelegate).IsOK()) require.True(t, stakeHandler(ctx, msgDelegate).IsOK())
// Update sk's LastValidatorPower/LastTotalPowers.
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
// 40 tokens left after delegating 60 of them // 40 tokens left after delegating 60 of them
amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom) amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
require.Equal(t, int64(40), amt.Int64()) require.Equal(t, int64(40), amt.Int64())

View File

@ -80,7 +80,7 @@ func (k Keeper) Hooks() Hooks { return Hooks{k} }
func (h Hooks) OnValidatorCreated(ctx sdk.Context, addr sdk.ValAddress) { func (h Hooks) OnValidatorCreated(ctx sdk.Context, addr sdk.ValAddress) {
h.k.onValidatorCreated(ctx, addr) h.k.onValidatorCreated(ctx, addr)
} }
func (h Hooks) OnValidatorCommissionChange(ctx sdk.Context, addr sdk.ValAddress) { func (h Hooks) OnValidatorModified(ctx sdk.Context, addr sdk.ValAddress) {
h.k.onValidatorModified(ctx, addr) h.k.onValidatorModified(ctx, addr)
} }
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, addr sdk.ValAddress) { func (h Hooks) OnValidatorRemoved(ctx sdk.Context, addr sdk.ValAddress) {

View File

@ -29,9 +29,9 @@ func TestSetGetFeePool(t *testing.T) {
ctx, _, keeper, _, _ := CreateTestInputDefault(t, false, 0) ctx, _, keeper, _, _ := CreateTestInputDefault(t, false, 0)
fp := types.InitialFeePool() fp := types.InitialFeePool()
fp.ValAccum.UpdateHeight = 777 fp.TotalValAccum.UpdateHeight = 777
keeper.SetFeePool(ctx, fp) keeper.SetFeePool(ctx, fp)
res := keeper.GetFeePool(ctx) res := keeper.GetFeePool(ctx)
require.Equal(t, fp.ValAccum, res.ValAccum) require.Equal(t, fp.TotalValAccum, res.TotalValAccum)
} }

View File

@ -114,7 +114,6 @@ func CreateTestInputAdvanced(t *testing.T, isCheckTx bool, initCoins int64,
sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, pk.Subspace(stake.DefaultParamspace), stake.DefaultCodespace) sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, pk.Subspace(stake.DefaultParamspace), stake.DefaultCodespace)
sk.SetPool(ctx, stake.InitialPool()) sk.SetPool(ctx, stake.InitialPool())
sk.SetParams(ctx, stake.DefaultParams()) sk.SetParams(ctx, stake.DefaultParams())
sk.InitIntraTxCounter(ctx)
// fill all the addresses with some coins, set the loose pool tokens simultaneously // fill all the addresses with some coins, set the loose pool tokens simultaneously
for _, addr := range addrs { for _, addr := range addrs {

View File

@ -50,15 +50,16 @@ func (k Keeper) WithdrawValidatorRewardsAll(ctx sdk.Context, operatorAddr sdk.Va
// withdraw self-delegation // withdraw self-delegation
height := ctx.BlockHeight() height := ctx.BlockHeight()
validator := k.stakeKeeper.Validator(ctx, operatorAddr) validator := k.stakeKeeper.Validator(ctx, operatorAddr)
lastValPower := k.stakeKeeper.GetLastValidatorPower(ctx, operatorAddr)
accAddr := sdk.AccAddress(operatorAddr.Bytes()) accAddr := sdk.AccAddress(operatorAddr.Bytes())
withdraw := k.getDelegatorRewardsAll(ctx, accAddr, height) withdraw := k.getDelegatorRewardsAll(ctx, accAddr, height)
// withdrawal validator commission rewards // withdrawal validator commission rewards
bondedTokens := k.stakeKeeper.TotalPower(ctx) lastTotalPower := k.stakeKeeper.GetLastTotalPower(ctx)
valInfo := k.GetValidatorDistInfo(ctx, operatorAddr) valInfo := k.GetValidatorDistInfo(ctx, operatorAddr)
feePool := k.GetFeePool(ctx) feePool := k.GetFeePool(ctx)
valInfo, feePool, commission := valInfo.WithdrawCommission(feePool, height, bondedTokens, valInfo, feePool, commission := valInfo.WithdrawCommission(feePool, height, lastTotalPower,
validator.GetPower(), validator.GetCommission()) lastValPower, validator.GetCommission())
withdraw = withdraw.Plus(commission) withdraw = withdraw.Plus(commission)
k.SetValidatorDistInfo(ctx, valInfo) k.SetValidatorDistInfo(ctx, valInfo)

View File

@ -21,7 +21,13 @@ func NewDelegationDistInfo(delegatorAddr sdk.AccAddress, valOperatorAddr sdk.Val
} }
} }
// withdraw rewards from delegator // Withdraw rewards from delegator.
// Among many things, it does:
// * updates validator info's total del accum.
// * calls vi.TakeFeePoolRewards, which:
// * updates validator info's FeePoolWithdrawalHeight, thus setting accum to 0.
// * updates fee pool to latest height and total val accum w/ given totalBonded.
// (see comment on TakeFeePoolRewards for more info).
func (di DelegationDistInfo) WithdrawRewards(fp FeePool, vi ValidatorDistInfo, func (di DelegationDistInfo) WithdrawRewards(fp FeePool, vi ValidatorDistInfo,
height int64, totalBonded, vdTokens, totalDelShares, delegatorShares, height int64, totalBonded, vdTokens, totalDelShares, delegatorShares,
commissionRate sdk.Dec) (DelegationDistInfo, ValidatorDistInfo, FeePool, DecCoins) { commissionRate sdk.Dec) (DelegationDistInfo, ValidatorDistInfo, FeePool, DecCoins) {

View File

@ -33,7 +33,7 @@ func TestWithdrawRewards(t *testing.T) {
validatorTokens, validatorDelShares, di1Shares, commissionRate) validatorTokens, validatorDelShares, di1Shares, commissionRate)
assert.Equal(t, height, di1.WithdrawalHeight) assert.Equal(t, height, di1.WithdrawalHeight)
assert.True(sdk.DecEq(t, sdk.NewDec(900), fp.ValAccum.Accum)) assert.True(sdk.DecEq(t, sdk.NewDec(900), fp.TotalValAccum.Accum))
assert.True(sdk.DecEq(t, sdk.NewDec(900), fp.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(900), fp.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(49), vi.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(49), vi.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(2), vi.PoolCommission[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(2), vi.PoolCommission[0].Amount))
@ -48,7 +48,7 @@ func TestWithdrawRewards(t *testing.T) {
validatorTokens, validatorDelShares, di2Shares, commissionRate) validatorTokens, validatorDelShares, di2Shares, commissionRate)
assert.Equal(t, height, di2.WithdrawalHeight) assert.Equal(t, height, di2.WithdrawalHeight)
assert.True(sdk.DecEq(t, sdk.NewDec(1800), fp.ValAccum.Accum)) assert.True(sdk.DecEq(t, sdk.NewDec(1800), fp.TotalValAccum.Accum))
assert.True(sdk.DecEq(t, sdk.NewDec(1800), fp.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(1800), fp.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(49), vi.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(49), vi.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(4), vi.PoolCommission[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(4), vi.PoolCommission[0].Amount))

View File

@ -1,7 +1,10 @@
package types package types
import ( import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
cmn "github.com/tendermint/tendermint/libs/common"
) )
// total accumulation tracker // total accumulation tracker
@ -29,25 +32,50 @@ func (ta TotalAccum) UpdateForNewHeight(height int64, accumCreatedPerBlock sdk.D
return ta return ta
} }
// update total validator accumulation factor for the new height
// CONTRACT: height should be greater than the old height
func (ta TotalAccum) UpdateForNewHeight_DEBUG(height int64, accumCreatedPerBlock sdk.Dec) TotalAccum {
blocks := height - ta.UpdateHeight
if blocks < 0 {
panic("reverse updated for new height")
}
if !accumCreatedPerBlock.IsZero() && blocks != 0 {
fmt.Println(
cmn.Blue(
fmt.Sprintf("FP Add %v * %v = %v, + %v (old) => %v (new)",
accumCreatedPerBlock.String(), sdk.NewInt(blocks),
accumCreatedPerBlock.MulInt(sdk.NewInt(blocks)).String(),
ta.Accum.String(),
ta.Accum.Add(accumCreatedPerBlock.MulInt(sdk.NewInt(blocks))).String(),
),
),
)
}
ta.Accum = ta.Accum.Add(accumCreatedPerBlock.MulInt(sdk.NewInt(blocks)))
ta.UpdateHeight = height
return ta
}
//___________________________________________________________________________________________ //___________________________________________________________________________________________
// global fee pool for distribution // global fee pool for distribution
type FeePool struct { type FeePool struct {
ValAccum TotalAccum `json:"val_accum"` // total valdator accum held by validators TotalValAccum TotalAccum `json:"val_accum"` // total valdator accum held by validators
Pool DecCoins `json:"pool"` // funds for all validators which have yet to be withdrawn Pool DecCoins `json:"pool"` // funds for all validators which have yet to be withdrawn
CommunityPool DecCoins `json:"community_pool"` // pool for community funds yet to be spent CommunityPool DecCoins `json:"community_pool"` // pool for community funds yet to be spent
} }
// update total validator accumulation factor // update total validator accumulation factor
// NOTE: Do not call this except from ValidatorDistInfo.TakeFeePoolRewards().
func (f FeePool) UpdateTotalValAccum(height int64, totalBondedTokens sdk.Dec) FeePool { func (f FeePool) UpdateTotalValAccum(height int64, totalBondedTokens sdk.Dec) FeePool {
f.ValAccum = f.ValAccum.UpdateForNewHeight(height, totalBondedTokens) f.TotalValAccum = f.TotalValAccum.UpdateForNewHeight_DEBUG(height, totalBondedTokens)
return f return f
} }
// zero fee pool // zero fee pool
func InitialFeePool() FeePool { func InitialFeePool() FeePool {
return FeePool{ return FeePool{
ValAccum: NewTotalAccum(0), TotalValAccum: NewTotalAccum(0),
Pool: DecCoins{}, Pool: DecCoins{},
CommunityPool: DecCoins{}, CommunityPool: DecCoins{},
} }

View File

@ -23,8 +23,8 @@ func TestUpdateTotalValAccum(t *testing.T) {
fp := InitialFeePool() fp := InitialFeePool()
fp = fp.UpdateTotalValAccum(5, sdk.NewDec(3)) fp = fp.UpdateTotalValAccum(5, sdk.NewDec(3))
require.True(sdk.DecEq(t, sdk.NewDec(15), fp.ValAccum.Accum)) require.True(sdk.DecEq(t, sdk.NewDec(15), fp.TotalValAccum.Accum))
fp = fp.UpdateTotalValAccum(8, sdk.NewDec(2)) fp = fp.UpdateTotalValAccum(8, sdk.NewDec(2))
require.True(sdk.DecEq(t, sdk.NewDec(21), fp.ValAccum.Accum)) require.True(sdk.DecEq(t, sdk.NewDec(21), fp.TotalValAccum.Accum))
} }

View File

@ -10,6 +10,8 @@ type StakeKeeper interface {
Validator(ctx sdk.Context, valAddr sdk.ValAddress) sdk.Validator Validator(ctx sdk.Context, valAddr sdk.ValAddress) sdk.Validator
ValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) sdk.Validator ValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) sdk.Validator
TotalPower(ctx sdk.Context) sdk.Dec TotalPower(ctx sdk.Context) sdk.Dec
GetLastTotalPower(ctx sdk.Context) sdk.Dec
GetLastValidatorPower(ctx sdk.Context, valAddr sdk.ValAddress) sdk.Dec
} }
// expected coin keeper // expected coin keeper

View File

@ -1,7 +1,10 @@
package types package types
import ( import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
cmn "github.com/tendermint/tendermint/libs/common"
) )
// distribution info for a particular validator // distribution info for a particular validator
@ -31,13 +34,21 @@ func (vi ValidatorDistInfo) UpdateTotalDelAccum(height int64, totalDelShares sdk
return vi return vi
} }
// move any available accumulated fees in the FeePool to the validator's pool // Move any available accumulated fees in the FeePool to the validator's pool.
// * updates validator info's FeePoolWithdrawalHeight, thus setting accum to 0.
// * updates fee pool to latest height and total val accum w/ given totalBonded.
// This is the only way to update the FeePool's validator TotalAccum.
// NOTE: This algorithm works as long as TakeFeePoolRewards is called after every power change.
// - called in ValidationDistInfo.WithdrawCommission.
// - called in DelegationDistInfo.WithdrawRewards.
// NOTE: When a delegator unbonds, say, onDelegationSharesModified ->
// WithdrawDelegationReward -> WithdrawRewards.
func (vi ValidatorDistInfo) TakeFeePoolRewards(fp FeePool, height int64, totalBonded, vdTokens, func (vi ValidatorDistInfo) TakeFeePoolRewards(fp FeePool, height int64, totalBonded, vdTokens,
commissionRate sdk.Dec) (ValidatorDistInfo, FeePool) { commissionRate sdk.Dec) (ValidatorDistInfo, FeePool) {
fp = fp.UpdateTotalValAccum(height, totalBonded) fp = fp.UpdateTotalValAccum(height, totalBonded)
if fp.ValAccum.Accum.IsZero() { if fp.TotalValAccum.Accum.IsZero() {
return vi, fp return vi, fp
} }
@ -45,16 +56,30 @@ func (vi ValidatorDistInfo) TakeFeePoolRewards(fp FeePool, height int64, totalBo
blocks := height - vi.FeePoolWithdrawalHeight blocks := height - vi.FeePoolWithdrawalHeight
vi.FeePoolWithdrawalHeight = height vi.FeePoolWithdrawalHeight = height
accum := vdTokens.MulInt(sdk.NewInt(blocks)) accum := vdTokens.MulInt(sdk.NewInt(blocks))
if accum.GT(fp.ValAccum.Accum) {
if !accum.IsZero() {
fmt.Println(
cmn.Red(
fmt.Sprintf("FP Sub %v * %v = %v, %v - _ => %v",
vdTokens.String(), sdk.NewInt(blocks),
accum.String(),
fp.TotalValAccum.Accum.String(),
fp.TotalValAccum.Accum.Sub(accum).String(),
),
),
)
}
if accum.GT(fp.TotalValAccum.Accum) {
panic("individual accum should never be greater than the total") panic("individual accum should never be greater than the total")
} }
withdrawalTokens := fp.Pool.MulDec(accum).QuoDec(fp.ValAccum.Accum) withdrawalTokens := fp.Pool.MulDec(accum).QuoDec(fp.TotalValAccum.Accum)
remainingTokens := fp.Pool.Minus(withdrawalTokens) remainingTokens := fp.Pool.Minus(withdrawalTokens)
commission := withdrawalTokens.MulDec(commissionRate) commission := withdrawalTokens.MulDec(commissionRate)
afterCommission := withdrawalTokens.Minus(commission) afterCommission := withdrawalTokens.Minus(commission)
fp.ValAccum.Accum = fp.ValAccum.Accum.Sub(accum) fp.TotalValAccum.Accum = fp.TotalValAccum.Accum.Sub(accum)
fp.Pool = remainingTokens fp.Pool = remainingTokens
vi.PoolCommission = vi.PoolCommission.Plus(commission) vi.PoolCommission = vi.PoolCommission.Plus(commission)
vi.Pool = vi.Pool.Plus(afterCommission) vi.Pool = vi.Pool.Plus(afterCommission)

View File

@ -29,13 +29,13 @@ func TestTakeFeePoolRewards(t *testing.T) {
fp.Pool = DecCoins{NewDecCoin("stake", 1000)} fp.Pool = DecCoins{NewDecCoin("stake", 1000)}
vi1, fp = vi1.TakeFeePoolRewards(fp, height, totalBondedTokens, validatorTokens1, commissionRate1) vi1, fp = vi1.TakeFeePoolRewards(fp, height, totalBondedTokens, validatorTokens1, commissionRate1)
require.True(sdk.DecEq(t, sdk.NewDec(900), fp.ValAccum.Accum)) require.True(sdk.DecEq(t, sdk.NewDec(900), fp.TotalValAccum.Accum))
assert.True(sdk.DecEq(t, sdk.NewDec(900), fp.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(900), fp.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(100-2), vi1.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(100-2), vi1.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(2), vi1.PoolCommission[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(2), vi1.PoolCommission[0].Amount))
vi2, fp = vi2.TakeFeePoolRewards(fp, height, totalBondedTokens, validatorTokens2, commissionRate2) vi2, fp = vi2.TakeFeePoolRewards(fp, height, totalBondedTokens, validatorTokens2, commissionRate2)
require.True(sdk.DecEq(t, sdk.NewDec(500), fp.ValAccum.Accum)) require.True(sdk.DecEq(t, sdk.NewDec(500), fp.TotalValAccum.Accum))
assert.True(sdk.DecEq(t, sdk.NewDec(500), fp.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(500), fp.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(400-12), vi2.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(400-12), vi2.Pool[0].Amount))
assert.True(sdk.DecEq(t, vi2.PoolCommission[0].Amount, sdk.NewDec(12))) assert.True(sdk.DecEq(t, vi2.PoolCommission[0].Amount, sdk.NewDec(12)))
@ -45,7 +45,7 @@ func TestTakeFeePoolRewards(t *testing.T) {
fp.Pool[0].Amount = fp.Pool[0].Amount.Add(sdk.NewDec(1000)) fp.Pool[0].Amount = fp.Pool[0].Amount.Add(sdk.NewDec(1000))
vi3, fp = vi3.TakeFeePoolRewards(fp, height, totalBondedTokens, validatorTokens3, commissionRate3) vi3, fp = vi3.TakeFeePoolRewards(fp, height, totalBondedTokens, validatorTokens3, commissionRate3)
require.True(sdk.DecEq(t, sdk.NewDec(500), fp.ValAccum.Accum)) require.True(sdk.DecEq(t, sdk.NewDec(500), fp.TotalValAccum.Accum))
assert.True(sdk.DecEq(t, sdk.NewDec(500), fp.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(500), fp.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(1000-40), vi3.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(1000-40), vi3.Pool[0].Amount))
assert.True(sdk.DecEq(t, vi3.PoolCommission[0].Amount, sdk.NewDec(40))) assert.True(sdk.DecEq(t, vi3.PoolCommission[0].Amount, sdk.NewDec(40)))
@ -67,7 +67,7 @@ func TestWithdrawCommission(t *testing.T) {
// for a more fun staring condition, have an non-withdraw update // for a more fun staring condition, have an non-withdraw update
vi, fp = vi.TakeFeePoolRewards(fp, height, totalBondedTokens, validatorTokens, commissionRate) vi, fp = vi.TakeFeePoolRewards(fp, height, totalBondedTokens, validatorTokens, commissionRate)
require.True(sdk.DecEq(t, sdk.NewDec(900), fp.ValAccum.Accum)) require.True(sdk.DecEq(t, sdk.NewDec(900), fp.TotalValAccum.Accum))
assert.True(sdk.DecEq(t, sdk.NewDec(900), fp.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(900), fp.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(100-2), vi.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(100-2), vi.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(2), vi.PoolCommission[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(2), vi.PoolCommission[0].Amount))
@ -77,7 +77,7 @@ func TestWithdrawCommission(t *testing.T) {
fp.Pool[0].Amount = fp.Pool[0].Amount.Add(sdk.NewDec(1000)) fp.Pool[0].Amount = fp.Pool[0].Amount.Add(sdk.NewDec(1000))
vi, fp, commissionRecv := vi.WithdrawCommission(fp, height, totalBondedTokens, validatorTokens, commissionRate) vi, fp, commissionRecv := vi.WithdrawCommission(fp, height, totalBondedTokens, validatorTokens, commissionRate)
require.True(sdk.DecEq(t, sdk.NewDec(1800), fp.ValAccum.Accum)) require.True(sdk.DecEq(t, sdk.NewDec(1800), fp.TotalValAccum.Accum))
assert.True(sdk.DecEq(t, sdk.NewDec(1800), fp.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(1800), fp.Pool[0].Amount))
assert.True(sdk.DecEq(t, sdk.NewDec(200-4), vi.Pool[0].Amount)) assert.True(sdk.DecEq(t, sdk.NewDec(200-4), vi.Pool[0].Amount))
assert.Zero(t, len(vi.PoolCommission)) assert.Zero(t, len(vi.PoolCommission))

View File

@ -50,7 +50,7 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall
} else { } else {
keeper.ds.IterateDelegations(ctx, vote.Voter, func(index int64, delegation sdk.Delegation) (stop bool) { keeper.ds.IterateDelegations(ctx, vote.Voter, func(index int64, delegation sdk.Delegation) (stop bool) {
valAddrStr := delegation.GetValidator().String() valAddrStr := delegation.GetValidatorAddr().String()
if val, ok := currValidators[valAddrStr]; ok { if val, ok := currValidators[valAddrStr]; ok {
val.Minus = val.Minus.Add(delegation.GetShares()) val.Minus = val.Minus.Add(delegation.GetShares())

View File

@ -62,7 +62,7 @@ func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, address sdk.ConsAddres
// nolint - unused hooks // nolint - unused hooks
func (h Hooks) OnValidatorCreated(_ sdk.Context, _ sdk.ValAddress) {} func (h Hooks) OnValidatorCreated(_ sdk.Context, _ sdk.ValAddress) {}
func (h Hooks) OnValidatorCommissionChange(_ sdk.Context, _ sdk.ValAddress) {} func (h Hooks) OnValidatorModified(_ sdk.Context, _ sdk.ValAddress) {}
func (h Hooks) OnValidatorRemoved(_ sdk.Context, _ sdk.ValAddress) {} func (h Hooks) OnValidatorRemoved(_ sdk.Context, _ sdk.ValAddress) {}
func (h Hooks) OnDelegationCreated(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {} func (h Hooks) OnDelegationCreated(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {}
func (h Hooks) OnDelegationSharesModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {} func (h Hooks) OnDelegationSharesModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {}

View File

@ -37,7 +37,8 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, vs sdk.ValidatorSet, paramspa
return keeper return keeper
} }
// handle a validator signing two blocks at the same height // handle a validator signing two blocks at the same height.
// power: power of the double-signing validator at the height of infraction.
func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractionHeight int64, timestamp time.Time, power int64) { func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractionHeight int64, timestamp time.Time, power int64) {
logger := ctx.Logger().With("module", "x/slashing") logger := ctx.Logger().With("module", "x/slashing")
time := ctx.BlockHeader().Time time := ctx.BlockHeader().Time
@ -70,7 +71,12 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
revisedFraction := k.capBySlashingPeriod(ctx, consAddr, fraction, distributionHeight) revisedFraction := k.capBySlashingPeriod(ctx, consAddr, fraction, distributionHeight)
logger.Info(fmt.Sprintf("Fraction slashed capped by slashing period from %v to %v", fraction, revisedFraction)) logger.Info(fmt.Sprintf("Fraction slashed capped by slashing period from %v to %v", fraction, revisedFraction))
// Slash validator // Slash validator.
// `power` is the int64 power of the validator as provided to/by
// Tendermint. This value is validator.Tokens as sent to Tendermint via
// ABCI, and now received as evidence.
// The revisedFraction (which is the new fraction to be slashed) is passed
// in separately to separately slash unbonding and rebonding delegations.
k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, revisedFraction) k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, revisedFraction)
// Jail validator if not already jailed // Jail validator if not already jailed

View File

@ -37,6 +37,7 @@ func (k Keeper) capBySlashingPeriod(ctx sdk.Context, address sdk.ConsAddress, fr
// This function retrieves the most recent slashing period starting // This function retrieves the most recent slashing period starting
// before a particular height - so the slashing period that was "in effect" // before a particular height - so the slashing period that was "in effect"
// at the time of an infraction committed at that height. // at the time of an infraction committed at that height.
// Slashing periods are created upon validator bonding.
func (k Keeper) getValidatorSlashingPeriodForHeight(ctx sdk.Context, address sdk.ConsAddress, height int64) (slashingPeriod ValidatorSlashingPeriod) { func (k Keeper) getValidatorSlashingPeriodForHeight(ctx sdk.Context, address sdk.ConsAddress, height int64) (slashingPeriod ValidatorSlashingPeriod) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
// Get the most recent slashing period at or before the infraction height // Get the most recent slashing period at or before the infraction height

View File

@ -26,7 +26,6 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [
keeper.SetPool(ctx, data.Pool) keeper.SetPool(ctx, data.Pool)
keeper.SetParams(ctx, data.Params) keeper.SetParams(ctx, data.Params)
keeper.InitIntraTxCounter(ctx)
for i, validator := range data.Validators { for i, validator := range data.Validators {
validator.BondIntraTxCounter = int16(i) // set the intra-tx counter to the order the validators are presented validator.BondIntraTxCounter = int16(i) // set the intra-tx counter to the order the validators are presented

View File

@ -148,7 +148,7 @@ func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keepe
return err.Result() return err.Result()
} }
validator.Commission = commission validator.Commission = commission
k.OnValidatorCommissionChange(ctx, msg.ValidatorAddr) k.OnValidatorModified(ctx, msg.ValidatorAddr)
} }
k.SetValidator(ctx, validator) k.SetValidator(ctx, validator)

View File

@ -889,21 +889,21 @@ func TestUnbondingWhenExcessValidators(t *testing.T) {
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
// apply TM updates // apply TM updates
keeper.ApplyAndReturnValidatorSetUpdates(ctx) keeper.ApplyAndReturnValidatorSetUpdates(ctx)
require.Equal(t, 1, len(keeper.GetValidatorsBonded(ctx))) require.Equal(t, 1, len(keeper.GetLastValidators(ctx)))
msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 30) msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 30)
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
// apply TM updates // apply TM updates
keeper.ApplyAndReturnValidatorSetUpdates(ctx) keeper.ApplyAndReturnValidatorSetUpdates(ctx)
require.Equal(t, 2, len(keeper.GetValidatorsBonded(ctx))) require.Equal(t, 2, len(keeper.GetLastValidators(ctx)))
msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], 10) msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], 10)
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
// apply TM updates // apply TM updates
keeper.ApplyAndReturnValidatorSetUpdates(ctx) keeper.ApplyAndReturnValidatorSetUpdates(ctx)
require.Equal(t, 2, len(keeper.GetValidatorsBonded(ctx))) require.Equal(t, 2, len(keeper.GetLastValidators(ctx)))
// unbond the valdator-2 // unbond the valdator-2
msgBeginUnbonding := NewMsgBeginUnbonding(sdk.AccAddress(validatorAddr2), validatorAddr2, sdk.NewDec(30)) msgBeginUnbonding := NewMsgBeginUnbonding(sdk.AccAddress(validatorAddr2), validatorAddr2, sdk.NewDec(30))
@ -916,7 +916,7 @@ func TestUnbondingWhenExcessValidators(t *testing.T) {
// because there are extra validators waiting to get in, the queued // because there are extra validators waiting to get in, the queued
// validator (aka. validator-1) should make it into the bonded group, thus // validator (aka. validator-1) should make it into the bonded group, thus
// the total number of validators should stay the same // the total number of validators should stay the same
vals := keeper.GetValidatorsBonded(ctx) vals := keeper.GetLastValidators(ctx)
require.Equal(t, 2, len(vals), "vals %v", vals) require.Equal(t, 2, len(vals), "vals %v", vals)
val1, found := keeper.GetValidator(ctx, validatorAddr1) val1, found := keeper.GetValidator(ctx, validatorAddr1)
require.True(t, found) require.True(t, found)

View File

@ -11,9 +11,9 @@ func (k Keeper) OnValidatorCreated(ctx sdk.Context, address sdk.ValAddress) {
k.hooks.OnValidatorCreated(ctx, address) k.hooks.OnValidatorCreated(ctx, address)
} }
} }
func (k Keeper) OnValidatorCommissionChange(ctx sdk.Context, address sdk.ValAddress) { func (k Keeper) OnValidatorModified(ctx sdk.Context, address sdk.ValAddress) {
if k.hooks != nil { if k.hooks != nil {
k.hooks.OnValidatorCommissionChange(ctx, address) k.hooks.OnValidatorModified(ctx, address)
} }
} }

View File

@ -53,12 +53,12 @@ func (k Keeper) Codespace() sdk.CodespaceType {
//_______________________________________________________________________ //_______________________________________________________________________
// load/save the pool // load the pool
func (k Keeper) GetPool(ctx sdk.Context) (pool types.Pool) { func (k Keeper) GetPool(ctx sdk.Context) (pool types.Pool) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
b := store.Get(PoolKey) b := store.Get(PoolKey)
if b == nil { if b == nil {
panic("Stored pool should not have been nil") panic("stored pool should not have been nil")
} }
k.cdc.MustUnmarshalBinary(b, &pool) k.cdc.MustUnmarshalBinary(b, &pool)
return return
@ -71,21 +71,73 @@ func (k Keeper) SetPool(ctx sdk.Context, pool types.Pool) {
store.Set(PoolKey, b) store.Set(PoolKey, b)
} }
//__________________________________________________________________________ //_______________________________________________________________________
// get the current in-block validator operation counter // Load the last total validator power.
func (k Keeper) InitIntraTxCounter(ctx sdk.Context) { func (k Keeper) GetLastTotalPower(ctx sdk.Context) (power sdk.Dec) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
b := store.Get(IntraTxCounterKey) b := store.Get(LastTotalPowerKey)
if b == nil { if b == nil {
k.SetIntraTxCounter(ctx, 0) panic("stored last total power should not have been nil")
} }
k.cdc.MustUnmarshalBinary(b, &power)
return
} }
// Set the last total validator power.
func (k Keeper) SetLastTotalPower(ctx sdk.Context, power sdk.Dec) {
if !power.IsInteger() {
panic("input power must be whole integer")
}
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(power)
store.Set(LastTotalPowerKey, b)
}
//_______________________________________________________________________
// Load the last validator power.
// Returns zero if the operator was not a validator last block.
func (k Keeper) GetLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress) (power sdk.Dec) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(GetLastValidatorPowerKey(operator))
if bz == nil {
return sdk.ZeroDec()
}
k.cdc.MustUnmarshalBinary(bz, &power)
return
}
func (k Keeper) powerToBytes(power sdk.Dec) []byte {
bz := k.cdc.MustMarshalBinary(power)
return bz
}
// Set the last validator power.
func (k Keeper) SetLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress, power sdk.Dec) {
if !power.IsInteger() {
panic("input power must be whole integer")
}
store := ctx.KVStore(k.storeKey)
bz := k.powerToBytes(power)
store.Set(GetLastValidatorPowerKey(operator), bz)
}
// Delete the last validator power.
func (k Keeper) DeleteLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress) {
store := ctx.KVStore(k.storeKey)
store.Delete(GetLastValidatorPowerKey(operator))
}
//__________________________________________________________________________
// get the current in-block validator operation counter // get the current in-block validator operation counter
func (k Keeper) GetIntraTxCounter(ctx sdk.Context) int16 { func (k Keeper) GetIntraTxCounter(ctx sdk.Context) int16 {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
b := store.Get(IntraTxCounterKey) b := store.Get(IntraTxCounterKey)
if b == nil {
return 0
}
var counter int16 var counter int16
k.cdc.MustUnmarshalBinary(b, &counter) k.cdc.MustUnmarshalBinary(b, &counter)
return counter return counter

View File

@ -16,20 +16,26 @@ var (
// TODO DEPRECATED: delete in next release and reorder keys // TODO DEPRECATED: delete in next release and reorder keys
// ParamKey = []byte{0x00} // key for parameters relating to staking // ParamKey = []byte{0x00} // key for parameters relating to staking
PoolKey = []byte{0x01} // key for the staking pools PoolKey = []byte{0x01} // key for the staking pools
ValidatorsKey = []byte{0x02} // prefix for each key to a validator IntraTxCounterKey = []byte{0x02} // key for intra-block tx index
ValidatorsByConsAddrKey = []byte{0x03} // prefix for each key to a validator index, by pubkey
ValidatorsBondedIndexKey = []byte{0x04} // prefix for each key to a validator index, for bonded validators // Last* values are const during a block.
ValidatorsByPowerIndexKey = []byte{0x05} // prefix for each key to a validator index, sorted by power LastValidatorPowerKey = []byte{0x11} // prefix for each key to a validator index, for bonded validators
IntraTxCounterKey = []byte{0x06} // key for intra-block tx index LastTotalPowerKey = []byte{0x12} // prefix for the total power
DelegationKey = []byte{0x07} // key for a delegation
UnbondingDelegationKey = []byte{0x08} // key for an unbonding-delegation ValidatorsKey = []byte{0x21} // prefix for each key to a validator
UnbondingDelegationByValIndexKey = []byte{0x09} // prefix for each key for an unbonding-delegation, by validator operator ValidatorsByConsAddrKey = []byte{0x22} // prefix for each key to a validator index, by pubkey
RedelegationKey = []byte{0x0A} // key for a redelegation ValidatorsByPowerIndexKey = []byte{0x23} // prefix for each key to a validator index, sorted by power
RedelegationByValSrcIndexKey = []byte{0x0B} // prefix for each key for an redelegation, by source validator operator
RedelegationByValDstIndexKey = []byte{0x0C} // prefix for each key for an redelegation, by destination validator operator DelegationKey = []byte{0x31} // key for a delegation
UnbondingQueueKey = []byte{0x0D} // prefix for the timestamps in unbonding queue UnbondingDelegationKey = []byte{0x32} // key for an unbonding-delegation
RedelegationQueueKey = []byte{0x0E} // prefix for the timestamps in redelegations queue UnbondingDelegationByValIndexKey = []byte{0x33} // prefix for each key for an unbonding-delegation, by validator operator
ValidatorQueueKey = []byte{0x0F} // prefix for the timestamps in validator queue RedelegationKey = []byte{0x34} // key for a redelegation
RedelegationByValSrcIndexKey = []byte{0x35} // prefix for each key for an redelegation, by source validator operator
RedelegationByValDstIndexKey = []byte{0x36} // prefix for each key for an redelegation, by destination validator operator
UnbondingQueueKey = []byte{0x41} // prefix for the timestamps in unbonding queue
RedelegationQueueKey = []byte{0x42} // prefix for the timestamps in redelegations queue
ValidatorQueueKey = []byte{0x43} // prefix for the timestamps in validator queue
) )
const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch
@ -46,9 +52,9 @@ func GetValidatorByConsAddrKey(addr sdk.ConsAddress) []byte {
return append(ValidatorsByConsAddrKey, addr.Bytes()...) return append(ValidatorsByConsAddrKey, addr.Bytes()...)
} }
// Get the validator operator address from ValBondedIndexKey // Get the validator operator address from LastValidatorPowerKey
func GetAddressFromValBondedIndexKey(IndexKey []byte) []byte { func AddressFromLastValidatorPowerKey(key []byte) []byte {
return IndexKey[1:] // remove prefix bytes return key[1:] // remove prefix bytes
} }
// get the validator by power index. // get the validator by power index.
@ -61,8 +67,8 @@ func GetValidatorsByPowerIndexKey(validator types.Validator, pool types.Pool) []
} }
// get the bonded validator index key for an operator address // get the bonded validator index key for an operator address
func GetBondedValidatorIndexKey(operator sdk.ValAddress) []byte { func GetLastValidatorPowerKey(operator sdk.ValAddress) []byte {
return append(ValidatorsBondedIndexKey, operator...) return append(LastValidatorPowerKey, operator...)
} }
// get the power ranking of a validator // get the power ranking of a validator

View File

@ -35,10 +35,10 @@ func TestGetValidatorPowerRank(t *testing.T) {
validator types.Validator validator types.Validator
wantHex string wantHex string
}{ }{
{val1, "050000000000000000ffffffffffffffffffff"}, {val1, "230000000000000000ffffffffffffffffffff"},
{val2, "050000000000000001ffffffffffffffffffff"}, {val2, "230000000000000001ffffffffffffffffffff"},
{val3, "05000000000000000affffffffffffffffffff"}, {val3, "23000000000000000affffffffffffffffffff"},
{val4, "050000010000000000ffffffffffffffffffff"}, {val4, "230000010000000000ffffffffffffffffffff"},
} }
for i, tt := range tests { for i, tt := range tests {
got := hex.EncodeToString(getValidatorPowerRank(tt.validator)) got := hex.EncodeToString(getValidatorPowerRank(tt.validator))
@ -55,11 +55,11 @@ func TestGetREDByValDstIndexKey(t *testing.T) {
wantHex string wantHex string
}{ }{
{sdk.AccAddress(addr1), sdk.ValAddress(addr1), sdk.ValAddress(addr1), {sdk.AccAddress(addr1), sdk.ValAddress(addr1), sdk.ValAddress(addr1),
"0c63d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f08609"}, "3663d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f08609"},
{sdk.AccAddress(addr1), sdk.ValAddress(addr2), sdk.ValAddress(addr3), {sdk.AccAddress(addr1), sdk.ValAddress(addr2), sdk.ValAddress(addr3),
"0c3ab62f0d93849be495e21e3e9013a517038f45bd63d771218209d8bd03c482f69dfba57310f086095ef3b5f25c54946d4a89fc0d09d2f126614540f2"}, "363ab62f0d93849be495e21e3e9013a517038f45bd63d771218209d8bd03c482f69dfba57310f086095ef3b5f25c54946d4a89fc0d09d2f126614540f2"},
{sdk.AccAddress(addr2), sdk.ValAddress(addr1), sdk.ValAddress(addr3), {sdk.AccAddress(addr2), sdk.ValAddress(addr1), sdk.ValAddress(addr3),
"0c3ab62f0d93849be495e21e3e9013a517038f45bd5ef3b5f25c54946d4a89fc0d09d2f126614540f263d771218209d8bd03c482f69dfba57310f08609"}, "363ab62f0d93849be495e21e3e9013a517038f45bd5ef3b5f25c54946d4a89fc0d09d2f126614540f263d771218209d8bd03c482f69dfba57310f08609"},
} }
for i, tt := range tests { for i, tt := range tests {
got := hex.EncodeToString(GetREDByValDstIndexKey(tt.delAddr, tt.valSrcAddr, tt.valDstAddr)) got := hex.EncodeToString(GetREDByValDstIndexKey(tt.delAddr, tt.valSrcAddr, tt.valDstAddr))
@ -76,11 +76,11 @@ func TestGetREDByValSrcIndexKey(t *testing.T) {
wantHex string wantHex string
}{ }{
{sdk.AccAddress(addr1), sdk.ValAddress(addr1), sdk.ValAddress(addr1), {sdk.AccAddress(addr1), sdk.ValAddress(addr1), sdk.ValAddress(addr1),
"0b63d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f08609"}, "3563d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f08609"},
{sdk.AccAddress(addr1), sdk.ValAddress(addr2), sdk.ValAddress(addr3), {sdk.AccAddress(addr1), sdk.ValAddress(addr2), sdk.ValAddress(addr3),
"0b5ef3b5f25c54946d4a89fc0d09d2f126614540f263d771218209d8bd03c482f69dfba57310f086093ab62f0d93849be495e21e3e9013a517038f45bd"}, "355ef3b5f25c54946d4a89fc0d09d2f126614540f263d771218209d8bd03c482f69dfba57310f086093ab62f0d93849be495e21e3e9013a517038f45bd"},
{sdk.AccAddress(addr2), sdk.ValAddress(addr1), sdk.ValAddress(addr3), {sdk.AccAddress(addr2), sdk.ValAddress(addr1), sdk.ValAddress(addr3),
"0b63d771218209d8bd03c482f69dfba57310f086095ef3b5f25c54946d4a89fc0d09d2f126614540f23ab62f0d93849be495e21e3e9013a517038f45bd"}, "3563d771218209d8bd03c482f69dfba57310f086095ef3b5f25c54946d4a89fc0d09d2f126614540f23ab62f0d93849be495e21e3e9013a517038f45bd"},
} }
for i, tt := range tests { for i, tt := range tests {
got := hex.EncodeToString(GetREDByValSrcIndexKey(tt.delAddr, tt.valSrcAddr, tt.valDstAddr)) got := hex.EncodeToString(GetREDByValSrcIndexKey(tt.delAddr, tt.valSrcAddr, tt.valDstAddr))

View File

@ -30,10 +30,10 @@ func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validato
// iterate through the active validator set and perform the provided function // iterate through the active validator set and perform the provided function
func (k Keeper) IterateValidatorsBonded(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) { func (k Keeper) IterateValidatorsBonded(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey) iterator := sdk.KVStorePrefixIterator(store, LastValidatorPowerKey)
i := int64(0) i := int64(0)
for ; iterator.Valid(); iterator.Next() { for ; iterator.Valid(); iterator.Next() {
address := GetAddressFromValBondedIndexKey(iterator.Key()) address := AddressFromLastValidatorPowerKey(iterator.Key())
validator, found := k.GetValidator(ctx, address) validator, found := k.GetValidator(ctx, address)
if !found { if !found {
panic(fmt.Sprintf("validator record not found for address: %v\n", address)) panic(fmt.Sprintf("validator record not found for address: %v\n", address))
@ -66,7 +66,7 @@ func (k Keeper) ValidatorByConsAddr(ctx sdk.Context, addr sdk.ConsAddress) sdk.V
return val return val
} }
// total power from the bond // total power from the bond (not last, but current)
func (k Keeper) TotalPower(ctx sdk.Context) sdk.Dec { func (k Keeper) TotalPower(ctx sdk.Context) sdk.Dec {
pool := k.GetPool(ctx) pool := k.GetPool(ctx)
return pool.BondedTokens return pool.BondedTokens

View File

@ -51,6 +51,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
} }
operatorAddress := validator.GetOperator() operatorAddress := validator.GetOperator()
k.OnValidatorModified(ctx, operatorAddress)
// Track remaining slash amount for the validator // Track remaining slash amount for the validator
// This will decrease when we slash unbondings and // This will decrease when we slash unbondings and
@ -97,10 +98,13 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
// cannot decrease balance below zero // cannot decrease balance below zero
tokensToBurn := sdk.MinDec(remainingSlashAmount, validator.Tokens) tokensToBurn := sdk.MinDec(remainingSlashAmount, validator.Tokens)
tokensToBurn = sdk.MaxDec(tokensToBurn, sdk.ZeroDec()) // defensive.
// burn validator's tokens and update the validator // Deduct from validator's bonded tokens and update the validator.
// The deducted tokens are returned to pool.LooseTokens.
validator = k.RemoveValidatorTokens(ctx, validator, tokensToBurn) validator = k.RemoveValidatorTokens(ctx, validator, tokensToBurn)
pool := k.GetPool(ctx) pool := k.GetPool(ctx)
// Burn the slashed tokens, which are now loose.
pool.LooseTokens = pool.LooseTokens.Sub(tokensToBurn) pool.LooseTokens = pool.LooseTokens.Sub(tokensToBurn)
k.SetPool(ctx, pool) k.SetPool(ctx, pool)

View File

@ -106,7 +106,6 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
keeper := NewKeeper(cdc, keyStake, tkeyStake, ck, pk.Subspace(DefaultParamspace), types.DefaultCodespace) keeper := NewKeeper(cdc, keyStake, tkeyStake, ck, pk.Subspace(DefaultParamspace), types.DefaultCodespace)
keeper.SetPool(ctx, types.InitialPool()) keeper.SetPool(ctx, types.InitialPool())
keeper.SetParams(ctx, types.DefaultParams()) keeper.SetParams(ctx, types.DefaultParams())
keeper.InitIntraTxCounter(ctx)
// fill all the addresses with some coins, set the loose pool tokens simultaneously // fill all the addresses with some coins, set the loose pool tokens simultaneously
for _, addr := range Addrs { for _, addr := range Addrs {

View File

@ -11,7 +11,14 @@ import (
"github.com/cosmos/cosmos-sdk/x/stake/types" "github.com/cosmos/cosmos-sdk/x/stake/types"
) )
// Apply and return accumulated updates to the bonded validator set // Apply and return accumulated updates to the bonded validator set. Also,
// * Updates the active valset as keyed by LastValidatorPowerKey.
// * Updates the total power as keyed by LastTotalPowerKey.
// * Updates validator status' according to updated powers.
// * Updates the fee pool bonded vs loose tokens.
// * Updates relevant indices.
// It gets called once after genesis, another time maybe after genesis transactions,
// then once at every EndBlock.
// //
// CONTRACT: Only validators with non-zero power or zero-power that were bonded // CONTRACT: Only validators with non-zero power or zero-power that were bonded
// at the previous block height or were removed from the validator set entirely // at the previous block height or were removed from the validator set entirely
@ -20,11 +27,14 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
maxValidators := k.GetParams(ctx).MaxValidators maxValidators := k.GetParams(ctx).MaxValidators
totalPower := int64(0)
// retrieve last validator set // Retrieve the last validator set.
last := k.retrieveLastValidatorSet(ctx) // The persistent set is updated later in this function.
// (see LastValidatorPowerKey).
last := k.getLastValidatorsByAddr(ctx)
// iterate over validators, highest power to lowest // Iterate over validators, highest power to lowest.
iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey)
count := 0 count := 0
for ; iterator.Valid() && count < int(maxValidators); iterator.Next() { for ; iterator.Valid() && count < int(maxValidators); iterator.Next() {
@ -62,22 +72,22 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
oldPowerBytes, found := last[operatorBytes] oldPowerBytes, found := last[operatorBytes]
// calculate the new power bytes // calculate the new power bytes
newPowerBytes := validator.ABCIValidatorPowerBytes(k.cdc) newPower := validator.BondedTokens().RoundInt64()
newPowerBytes := k.powerToBytes(sdk.NewDec(newPower))
// update the validator set if power has changed // update the validator set if power has changed
if !found || !bytes.Equal(oldPowerBytes, newPowerBytes) { if !found || !bytes.Equal(oldPowerBytes, newPowerBytes) {
updates = append(updates, validator.ABCIValidatorUpdate()) updates = append(updates, validator.ABCIValidatorUpdate())
// set validator power on lookup index.
k.SetLastValidatorPower(ctx, operator, sdk.NewDec(newPower))
} }
// validator still in the validator set, so delete from the copy // validator still in the validator set, so delete from the copy
delete(last, operatorBytes) delete(last, operatorBytes)
// set the bonded validator index
store.Set(GetBondedValidatorIndexKey(operator), newPowerBytes)
// keep count // keep count
count++ count++
totalPower += newPower
} }
// sort the no-longer-bonded validators // sort the no-longer-bonded validators
@ -98,11 +108,15 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
} }
// delete from the bonded validator index // delete from the bonded validator index
store.Delete(GetBondedValidatorIndexKey(operator)) k.DeleteLastValidatorPower(ctx, operator)
// update the validator set // update the validator set
updates = append(updates, validator.ABCIValidatorUpdateZero()) updates = append(updates, validator.ABCIValidatorUpdateZero())
}
// set total power on lookup index if there are any updates
if len(updates) > 0 {
k.SetLastTotalPower(ctx, sdk.NewDec(totalPower))
} }
return updates return updates
@ -237,11 +251,11 @@ func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Vali
// map of operator addresses to serialized power // map of operator addresses to serialized power
type validatorsByAddr map[[sdk.AddrLen]byte][]byte type validatorsByAddr map[[sdk.AddrLen]byte][]byte
// retrieve the last validator set // get the last validator set
func (k Keeper) retrieveLastValidatorSet(ctx sdk.Context) validatorsByAddr { func (k Keeper) getLastValidatorsByAddr(ctx sdk.Context) validatorsByAddr {
last := make(validatorsByAddr) last := make(validatorsByAddr)
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey) iterator := sdk.KVStorePrefixIterator(store, LastValidatorPowerKey)
for ; iterator.Valid(); iterator.Next() { for ; iterator.Valid(); iterator.Next() {
var operator [sdk.AddrLen]byte var operator [sdk.AddrLen]byte
copy(operator[:], iterator.Key()[1:]) copy(operator[:], iterator.Key()[1:])

View File

@ -235,24 +235,24 @@ func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve uint16) (validators [
} }
// get the group of the bonded validators // get the group of the bonded validators
func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []types.Validator) { func (k Keeper) GetLastValidators(ctx sdk.Context) (validators []types.Validator) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
// add the actual validator power sorted store // add the actual validator power sorted store
maxValidators := k.MaxValidators(ctx) maxValidators := k.MaxValidators(ctx)
validators = make([]types.Validator, maxValidators) validators = make([]types.Validator, maxValidators)
iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey) iterator := sdk.KVStorePrefixIterator(store, LastValidatorPowerKey)
defer iterator.Close() defer iterator.Close()
i := 0 i := 0
for ; iterator.Valid(); iterator.Next() { for ; iterator.Valid(); iterator.Next() {
// sanity check // sanity check
if i > int(maxValidators-1) { if i >= int(maxValidators) {
panic("maxValidators is less than the number of records in ValidatorsBonded Store, store should have been updated") panic("more validators than maxValidators found")
} }
address := GetAddressFromValBondedIndexKey(iterator.Key()) address := AddressFromLastValidatorPowerKey(iterator.Key())
validator := k.mustGetValidator(ctx, address) validator := k.mustGetValidator(ctx, address)
validators[i] = validator validators[i] = validator
@ -261,7 +261,7 @@ func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []types.Validat
return validators[:i] // trim return validators[:i] // trim
} }
// get the group of bonded validators sorted by power-rank // get the current group of bonded validators sorted by power-rank
func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator { func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
maxValidators := k.MaxValidators(ctx) maxValidators := k.MaxValidators(ctx)

View File

@ -49,7 +49,7 @@ func TestSetValidator(t *testing.T) {
assert.True(ValEq(t, validator, resVal)) assert.True(ValEq(t, validator, resVal))
require.True(t, found) require.True(t, found)
resVals := keeper.GetValidatorsBonded(ctx) resVals := keeper.GetLastValidators(ctx)
require.Equal(t, 1, len(resVals)) require.Equal(t, 1, len(resVals))
assert.True(ValEq(t, validator, resVals[0])) assert.True(ValEq(t, validator, resVals[0]))
@ -191,7 +191,7 @@ func TestSlashToZeroPowerRemoved(t *testing.T) {
require.False(t, found) require.False(t, found)
} }
// This function tests UpdateValidator, GetValidator, GetValidatorsBonded, RemoveValidator // This function tests UpdateValidator, GetValidator, GetLastValidators, RemoveValidator
func TestValidatorBasics(t *testing.T) { func TestValidatorBasics(t *testing.T) {
ctx, _, keeper := CreateTestInput(t, false, 1000) ctx, _, keeper := CreateTestInput(t, false, 1000)
pool := keeper.GetPool(ctx) pool := keeper.GetPool(ctx)
@ -213,7 +213,7 @@ func TestValidatorBasics(t *testing.T) {
// check the empty keeper first // check the empty keeper first
_, found := keeper.GetValidator(ctx, addrVals[0]) _, found := keeper.GetValidator(ctx, addrVals[0])
require.False(t, found) require.False(t, found)
resVals := keeper.GetValidatorsBonded(ctx) resVals := keeper.GetLastValidators(ctx)
require.Zero(t, len(resVals)) require.Zero(t, len(resVals))
resVals = keeper.GetValidators(ctx, 2) resVals = keeper.GetValidators(ctx, 2)
@ -237,7 +237,7 @@ func TestValidatorBasics(t *testing.T) {
require.True(t, found) require.True(t, found)
assert.True(ValEq(t, validators[0], resVal)) assert.True(ValEq(t, validators[0], resVal))
resVals = keeper.GetValidatorsBonded(ctx) resVals = keeper.GetLastValidators(ctx)
require.Equal(t, 1, len(resVals)) require.Equal(t, 1, len(resVals))
assert.True(ValEq(t, validators[0], resVals[0])) assert.True(ValEq(t, validators[0], resVals[0]))
assert.Equal(t, sdk.Bonded, validators[0].Status) assert.Equal(t, sdk.Bonded, validators[0].Status)
@ -255,7 +255,7 @@ func TestValidatorBasics(t *testing.T) {
require.True(t, found) require.True(t, found)
assert.True(ValEq(t, validators[0], resVal)) assert.True(ValEq(t, validators[0], resVal))
resVals = keeper.GetValidatorsBonded(ctx) resVals = keeper.GetLastValidators(ctx)
require.Equal(t, 1, len(resVals)) require.Equal(t, 1, len(resVals))
assert.True(ValEq(t, validators[0], resVals[0])) assert.True(ValEq(t, validators[0], resVals[0]))
@ -269,7 +269,7 @@ func TestValidatorBasics(t *testing.T) {
require.True(t, found) require.True(t, found)
assert.True(ValEq(t, validators[2], resVal)) assert.True(ValEq(t, validators[2], resVal))
resVals = keeper.GetValidatorsBonded(ctx) resVals = keeper.GetLastValidators(ctx)
require.Equal(t, 3, len(resVals)) require.Equal(t, 3, len(resVals))
assert.True(ValEq(t, validators[0], resVals[0])) // order doesn't matter here assert.True(ValEq(t, validators[0], resVals[0])) // order doesn't matter here
assert.True(ValEq(t, validators[1], resVals[1])) assert.True(ValEq(t, validators[1], resVals[1]))

View File

@ -39,12 +39,13 @@ var (
GetDelegationKey = keeper.GetDelegationKey GetDelegationKey = keeper.GetDelegationKey
GetDelegationsKey = keeper.GetDelegationsKey GetDelegationsKey = keeper.GetDelegationsKey
PoolKey = keeper.PoolKey PoolKey = keeper.PoolKey
IntraTxCounterKey = keeper.IntraTxCounterKey
LastValidatorPowerKey = keeper.LastValidatorPowerKey
LastTotalPowerKey = keeper.LastTotalPowerKey
ValidatorsKey = keeper.ValidatorsKey ValidatorsKey = keeper.ValidatorsKey
ValidatorsByConsAddrKey = keeper.ValidatorsByConsAddrKey ValidatorsByConsAddrKey = keeper.ValidatorsByConsAddrKey
ValidatorsBondedIndexKey = keeper.ValidatorsBondedIndexKey
ValidatorsByPowerIndexKey = keeper.ValidatorsByPowerIndexKey ValidatorsByPowerIndexKey = keeper.ValidatorsByPowerIndexKey
DelegationKey = keeper.DelegationKey DelegationKey = keeper.DelegationKey
IntraTxCounterKey = keeper.IntraTxCounterKey
GetUBDKey = keeper.GetUBDKey GetUBDKey = keeper.GetUBDKey
GetUBDByValIndexKey = keeper.GetUBDByValIndexKey GetUBDByValIndexKey = keeper.GetUBDByValIndexKey
GetUBDsKey = keeper.GetUBDsKey GetUBDsKey = keeper.GetUBDsKey

View File

@ -104,8 +104,8 @@ func (d Delegation) Equal(d2 Delegation) bool {
var _ sdk.Delegation = Delegation{} var _ sdk.Delegation = Delegation{}
// nolint - for sdk.Delegation // nolint - for sdk.Delegation
func (d Delegation) GetDelegator() sdk.AccAddress { return d.DelegatorAddr } func (d Delegation) GetDelegatorAddr() sdk.AccAddress { return d.DelegatorAddr }
func (d Delegation) GetValidator() sdk.ValAddress { return d.ValidatorAddr } func (d Delegation) GetValidatorAddr() sdk.ValAddress { return d.ValidatorAddr }
func (d Delegation) GetShares() sdk.Dec { return d.Shares } func (d Delegation) GetShares() sdk.Dec { return d.Shares }
// HumanReadableString returns a human readable string representation of a // HumanReadableString returns a human readable string representation of a

View File

@ -314,12 +314,6 @@ func (v Validator) ABCIValidatorUpdate() abci.ValidatorUpdate {
} }
} }
// ABCIValidatorPowerBytes
func (v Validator) ABCIValidatorPowerBytes(cdc *codec.Codec) []byte {
power := v.BondedTokens().RoundInt64()
return cdc.MustMarshalBinary(power)
}
// ABCIValidatorUpdateZero returns an abci.ValidatorUpdate from a staked validator type // ABCIValidatorUpdateZero returns an abci.ValidatorUpdate from a staked validator type
// with zero power used for validator updates. // with zero power used for validator updates.
func (v Validator) ABCIValidatorUpdateZero() abci.ValidatorUpdate { func (v Validator) ABCIValidatorUpdateZero() abci.ValidatorUpdate {