diff --git a/types/stake.go b/types/stake.go index eb3f660820..e48577c0bf 100644 --- a/types/stake.go +++ b/types/stake.go @@ -43,6 +43,7 @@ type Validator interface { GetOwner() AccAddress // owner AccAddress to receive/return validators coins GetPubKey() crypto.PubKey // validation pubkey GetPower() Rat // validation power + GetTokens() Rat // validation tokens GetDelegatorShares() Rat // Total out standing delegator shares GetBondHeight() int64 // height in which the validator became active } diff --git a/x/stake/simulation/invariants.go b/x/stake/simulation/invariants.go index 92dd317d02..e4869693cf 100644 --- a/x/stake/simulation/invariants.go +++ b/x/stake/simulation/invariants.go @@ -30,8 +30,8 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim ctx := app.NewContext(false, abci.Header{}) pool := k.GetPool(ctx) - // Loose tokens should equal coin supply plus unbonding delegations loose := sdk.ZeroInt() + bonded := sdk.ZeroRat() am.IterateAccounts(ctx, func(acc auth.Account) bool { loose = loose.Add(acc.GetCoins().AmountOf("steak")) return false @@ -40,18 +40,22 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim loose = loose.Add(ubd.Balance.Amount) return false }) - require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", - pool.LooseTokens.RoundInt64(), loose.Int64(), log) - - // Bonded tokens should equal sum of tokens with bonded validators - bonded := sdk.ZeroRat() k.IterateValidators(ctx, func(_ int64, validator sdk.Validator) bool { switch validator.GetStatus() { case sdk.Bonded: bonded = bonded.Add(validator.GetPower()) + case sdk.Unbonding: + case sdk.Unbonded: + loose = loose.Add(validator.GetTokens().RoundInt()) } return false }) + + // Loose tokens should equal coin supply plus unbonding delegations plus tokens on unbonded validators + require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", + pool.LooseTokens.RoundInt64(), loose.Int64(), log) + + // Bonded tokens should equal sum of tokens with bonded validators require.True(t, pool.BondedTokens.Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators\nlog: %s", log) // TODO Inflation check on total supply diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index ed109830f0..ee1cb5a442 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -406,6 +406,7 @@ func (v Validator) GetStatus() sdk.BondStatus { return v.Status } func (v Validator) GetOwner() sdk.AccAddress { return v.Owner } func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey } func (v Validator) GetPower() sdk.Rat { return v.BondedTokens() } +func (v Validator) GetTokens() sdk.Rat { return v.Tokens } func (v Validator) GetDelegatorShares() sdk.Rat { return v.DelegatorShares } func (v Validator) GetBondHeight() int64 { return v.BondHeight }