fix tests, pool.TotalSupply -> pool.TokenSupply()

This commit is contained in:
rigelrozanski 2018-05-22 18:50:59 -04:00
parent db9fd51d1c
commit 41458956a1
10 changed files with 192 additions and 203 deletions

View File

@ -155,7 +155,7 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso
}
acc := NewGenesisAccount(&accAuth)
genaccs[i] = acc
stakeData.Pool.TotalSupply += freeFermionsAcc // increase the supply
stakeData.Pool.LooseUnbondedTokens += freeFermionsAcc // increase the supply
// add the validator
if len(genTx.Name) > 0 {
@ -165,7 +165,6 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso
stakeData.Validators = append(stakeData.Validators, validator)
// pool logic
stakeData.Pool.TotalSupply += freeFermionVal
stakeData.Pool.BondedTokens += freeFermionVal
stakeData.Pool.BondedShares = sdk.NewRat(stakeData.Pool.BondedTokens)
}

View File

@ -1,7 +1,6 @@
package stake
import (
"fmt"
"strconv"
"testing"
@ -225,14 +224,12 @@ func TestMultipleMsgDeclareCandidacy(t *testing.T) {
// bond them all
for i, validatorAddr := range validatorAddrs {
fmt.Printf("debug i: %v\n", i)
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[i], 10)
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
//Check that the account is bonded
validators := keeper.GetValidators(ctx, 100)
fmt.Printf("debug validators: %v\n", validators)
require.Equal(t, (i + 1), len(validators))
val := validators[i]
balanceExpd := initBond - 10

View File

@ -38,7 +38,7 @@ func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.Address) (validator Valid
return k.getValidator(store, addr)
}
// get a single validator
// get a single validator (reuse store)
func (k Keeper) getValidator(store sdk.KVStore, addr sdk.Address) (validator Validator, found bool) {
b := store.Get(GetValidatorKey(addr))
if b == nil {
@ -48,6 +48,13 @@ func (k Keeper) getValidator(store sdk.KVStore, addr sdk.Address) (validator Val
return validator, true
}
// set the main record holding validator details
func (k Keeper) setValidator(ctx sdk.Context, validator Validator) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(validator)
store.Set(GetValidatorKey(validator.Owner), bz)
}
// Get the set of all validators with no limits, used during genesis dump
func (k Keeper) getAllValidators(ctx sdk.Context) (validators Validators) {
store := ctx.KVStore(k.storeKey)
@ -89,100 +96,6 @@ func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve int16) (validators Va
return validators[:i] // trim
}
func (k Keeper) setValidator(ctx sdk.Context, validator Validator) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(validator)
store.Set(GetValidatorKey(validator.Owner), bz)
}
func (k Keeper) updateValidator(ctx sdk.Context, validator Validator) Validator {
store := ctx.KVStore(k.storeKey)
pool := k.getPool(store)
ownerAddr := validator.Owner
// always update the main list ordered by owner address before exiting
defer func() {
bz := k.cdc.MustMarshalBinary(validator)
store.Set(GetValidatorKey(ownerAddr), bz)
}()
// retreive the old validator record
oldValidator, oldFound := k.GetValidator(ctx, ownerAddr)
powerIncreasing := false
if oldFound {
// if the voting power/status is the same no need to update any of the other indexes
// TODO will need to implement this to have regard for "unrevoke" transaction however
// it shouldn't return here under that transaction
if oldValidator.Status() == validator.Status() &&
oldValidator.PoolShares.Equal(validator.PoolShares) {
return validator
} else if oldValidator.PoolShares.Bonded().LT(validator.PoolShares.Bonded()) {
powerIncreasing = true
}
}
// update the list ordered by voting power
if oldFound {
store.Delete(GetValidatorsByPowerKey(oldValidator, pool))
}
store.Set(GetValidatorsByPowerKey(validator, pool), validator.Owner)
// if already a validator, copy the old block height and counter, else set them
if oldFound && oldValidator.Status() == sdk.Bonded {
validator.BondHeight = oldValidator.BondHeight
validator.BondIntraTxCounter = oldValidator.BondIntraTxCounter
} else {
validator.BondHeight = ctx.BlockHeight()
counter := k.getIntraTxCounter(ctx)
validator.BondIntraTxCounter = counter
k.setIntraTxCounter(ctx, counter+1)
}
// efficiency case:
// if already bonded and power increasing only need to update tendermint
if powerIncreasing && oldValidator.Status() == sdk.Bonded {
bz := k.cdc.MustMarshalBinary(validator.abciValidator(k.cdc))
store.Set(GetTendermintUpdatesKey(ownerAddr), bz)
return validator
}
// TODO efficiency case:
// if was unbonded/or is a new validator - and the new power is less than the cliff validator
// update the validator set for this validator
updatedVal := k.updateBondedValidatorsNew(ctx, store, validator)
if updatedVal.Owner != nil { // updates to validator occured to be updated
validator = updatedVal
}
return validator
}
func (k Keeper) removeValidator(ctx sdk.Context, address sdk.Address) {
// first retreive the old validator record
validator, found := k.GetValidator(ctx, address)
if !found {
return
}
// delete the old validator record
store := ctx.KVStore(k.storeKey)
pool := k.getPool(store)
store.Delete(GetValidatorKey(address))
store.Delete(GetValidatorsByPowerKey(validator, pool))
// delete from the current and power weighted validator groups if the validator
// is bonded - and add validator with zero power to the validator updates
if store.Get(GetValidatorsBondedKey(validator.PubKey)) == nil {
return
}
store.Delete(GetValidatorsBondedKey(validator.PubKey))
bz := k.cdc.MustMarshalBinary(validator.abciValidatorZero(k.cdc))
store.Set(GetTendermintUpdatesKey(address), bz)
}
//___________________________________________________________________________
// get the group of the bonded validators
@ -240,6 +153,101 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []Validator {
return validators[:i] // trim
}
//_________________________________________________________________________
// Accumulated updates to the active/bonded validator set for tendermint
// get the most recently updated validators
func (k Keeper) getTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) {
store := ctx.KVStore(k.storeKey)
iterator := store.SubspaceIterator(TendermintUpdatesKey) //smallest to largest
for ; iterator.Valid(); iterator.Next() {
valBytes := iterator.Value()
var val abci.Validator
k.cdc.MustUnmarshalBinary(valBytes, &val)
updates = append(updates, val)
}
iterator.Close()
return
}
// remove all validator update entries after applied to Tendermint
func (k Keeper) clearTendermintUpdates(ctx sdk.Context) {
store := ctx.KVStore(k.storeKey)
// delete subspace
iterator := store.SubspaceIterator(TendermintUpdatesKey)
for ; iterator.Valid(); iterator.Next() {
store.Delete(iterator.Key())
}
iterator.Close()
}
//___________________________________________________________________________
func (k Keeper) updateValidator(ctx sdk.Context, validator Validator) Validator {
store := ctx.KVStore(k.storeKey)
pool := k.getPool(store)
ownerAddr := validator.Owner
// always update the main list ordered by owner address before exiting
defer func() {
bz := k.cdc.MustMarshalBinary(validator)
store.Set(GetValidatorKey(ownerAddr), bz)
}()
// retreive the old validator record
oldValidator, oldFound := k.GetValidator(ctx, ownerAddr)
powerIncreasing := false
if oldFound {
// if the voting power/status is the same no need to update any of the other indexes
// TODO will need to implement this to have regard for "unrevoke" transaction however
// it shouldn't return here under that transaction
if oldValidator.Status() == validator.Status() &&
oldValidator.PoolShares.Equal(validator.PoolShares) {
return validator
} else if oldValidator.PoolShares.Bonded().LT(validator.PoolShares.Bonded()) {
powerIncreasing = true
}
}
// if already a validator, copy the old block height and counter, else set them
if oldFound && oldValidator.Status() == sdk.Bonded {
validator.BondHeight = oldValidator.BondHeight
validator.BondIntraTxCounter = oldValidator.BondIntraTxCounter
} else {
validator.BondHeight = ctx.BlockHeight()
counter := k.getIntraTxCounter(ctx)
validator.BondIntraTxCounter = counter
k.setIntraTxCounter(ctx, counter+1)
}
// update the list ordered by voting power
if oldFound {
store.Delete(GetValidatorsByPowerKey(oldValidator, pool))
}
store.Set(GetValidatorsByPowerKey(validator, pool), validator.Owner)
// efficiency case:
// if already bonded and power increasing only need to update tendermint
if powerIncreasing && oldValidator.Status() == sdk.Bonded {
bz := k.cdc.MustMarshalBinary(validator.abciValidator(k.cdc))
store.Set(GetTendermintUpdatesKey(ownerAddr), bz)
return validator
}
// TODO efficiency case:
// if was unbonded/or is a new validator - and the new power is less than the cliff validator
// update the validator set for this validator
updatedVal := k.updateBondedValidatorsNew(ctx, store, validator)
if updatedVal.Owner != nil { // updates to validator occured to be updated
validator = updatedVal
}
return validator
}
// XXX TODO build in consideration for revoked
//
// Update the validator group and kick out any old validators. In addition this
@ -262,11 +270,11 @@ func (k Keeper) updateBondedValidatorsNew(ctx sdk.Context, store sdk.KVStore,
newValidator Validator) (updatedVal Validator) {
// clear the current validators store, add to the ToKickOut temp store
toKickOut := make(map[string]int8) // map[key]value
toKickOut := make(map[string]byte)
iterator := store.SubspaceIterator(ValidatorsBondedKey)
for ; iterator.Valid(); iterator.Next() {
ownerAddr := iterator.Value()
toKickOut[string(ownerAddr)] = 0 // dummy set, only need key
toKickOut[string(ownerAddr)] = 0 // set anything
}
iterator.Close()
@ -298,12 +306,7 @@ func (k Keeper) updateBondedValidatorsNew(ctx sdk.Context, store sdk.KVStore,
_, found := toKickOut[string(ownerAddr)]
if found {
// remove from ToKickOut group
delete(toKickOut, string(ownerAddr))
// XXX also add to the current validators group
//store.Set(GetValidatorsBondedKey(validator.PubKey), validator.Owner)
} else {
// if it wasn't in the toKickOut group it means
@ -340,9 +343,6 @@ func (k Keeper) unbondValidator(ctx sdk.Context, store sdk.KVStore, validator Va
panic(fmt.Sprintf("should not already be be unbonded, validator: %v\n", validator))
}
// XXX first delete the old record in the pool
//store.Delete(GetValidatorsByPowerKey(validator, pool))
// set the status
validator, pool = validator.UpdateStatus(pool, sdk.Unbonded)
k.setPool(ctx, pool)
@ -350,7 +350,6 @@ func (k Keeper) unbondValidator(ctx sdk.Context, store sdk.KVStore, validator Va
// save the now unbonded validator record
bzVal := k.cdc.MustMarshalBinary(validator)
store.Set(GetValidatorKey(validator.Owner), bzVal)
// XXX store.Set(GetValidatorsByPowerKey(validator, pool), validator.Owner)
// add to accumulated changes for tendermint
bzABCI := k.cdc.MustMarshalBinary(validator.abciValidatorZero(k.cdc))
@ -369,9 +368,6 @@ func (k Keeper) bondValidator(ctx sdk.Context, store sdk.KVStore, validator Vali
panic(fmt.Sprintf("should not already be be bonded, validator: %v\n", validator))
}
// XXX first delete the old record in the pool
//store.Delete(GetValidatorsByPowerKey(validator, pool))
// set the status
validator, pool = validator.UpdateStatus(pool, sdk.Bonded)
k.setPool(ctx, pool)
@ -379,7 +375,6 @@ func (k Keeper) bondValidator(ctx sdk.Context, store sdk.KVStore, validator Vali
// save the now bonded validator record to the three referenced stores
bzVal := k.cdc.MustMarshalBinary(validator)
store.Set(GetValidatorKey(validator.Owner), bzVal)
// XXX store.Set(GetValidatorsByPowerKey(validator, pool), validator.Owner)
store.Set(GetValidatorsBondedKey(validator.PubKey), validator.Owner)
// add to accumulated changes for tendermint
@ -389,34 +384,29 @@ func (k Keeper) bondValidator(ctx sdk.Context, store sdk.KVStore, validator Vali
return validator
}
//_________________________________________________________________________
// Accumulated updates to the active/bonded validator set for tendermint
func (k Keeper) removeValidator(ctx sdk.Context, address sdk.Address) {
// get the most recently updated validators
func (k Keeper) getTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) {
store := ctx.KVStore(k.storeKey)
iterator := store.SubspaceIterator(TendermintUpdatesKey) //smallest to largest
for ; iterator.Valid(); iterator.Next() {
valBytes := iterator.Value()
var val abci.Validator
k.cdc.MustUnmarshalBinary(valBytes, &val)
updates = append(updates, val)
// first retreive the old validator record
validator, found := k.GetValidator(ctx, address)
if !found {
return
}
iterator.Close()
return
}
// remove all validator update entries after applied to Tendermint
func (k Keeper) clearTendermintUpdates(ctx sdk.Context) {
// delete the old validator record
store := ctx.KVStore(k.storeKey)
pool := k.getPool(store)
store.Delete(GetValidatorKey(address))
store.Delete(GetValidatorsByPowerKey(validator, pool))
// delete subspace
iterator := store.SubspaceIterator(TendermintUpdatesKey)
for ; iterator.Valid(); iterator.Next() {
store.Delete(iterator.Key())
// delete from the current and power weighted validator groups if the validator
// is bonded - and add validator with zero power to the validator updates
if store.Get(GetValidatorsBondedKey(validator.PubKey)) == nil {
return
}
iterator.Close()
store.Delete(GetValidatorsBondedKey(validator.PubKey))
bz := k.cdc.MustMarshalBinary(validator.abciValidatorZero(k.cdc))
store.Set(GetTendermintUpdatesKey(address), bz)
}
//_____________________________________________________________________

View File

@ -283,6 +283,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
require.True(t, found)
}
resValidators := keeper.GetValidatorsByPower(ctx)
require.Equal(t, nMax, uint16(len(resValidators)))
assert.True(ValEq(t, validators[2], resValidators[0]))
assert.True(ValEq(t, validators[3], resValidators[1]))
@ -402,7 +403,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) {
assert.True(ValEq(t, validators[3], resValidators[1]))
// test a swap in voting power
validators[0].PoolShares = NewBondedShares(sdk.NewRat(600))
validators[0].PoolShares = NewUnbondedShares(sdk.NewRat(600))
validators[0] = keeper.updateValidator(ctx, validators[0])
resValidators = keeper.GetValidatorsByPower(ctx)
require.Equal(t, max, len(resValidators))
@ -418,7 +419,7 @@ func TestClearTendermintUpdates(t *testing.T) {
validators := make([]Validator, len(amts))
for i, amt := range amts {
validators[i] = NewValidator(addrs[i], pks[i], Description{})
validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt))
validators[i].PoolShares = NewUnbondedShares(sdk.NewRat(amt))
validators[i].DelegatorShares = sdk.NewRat(amt)
keeper.updateValidator(ctx, validators[i])
}
@ -437,7 +438,7 @@ func TestGetTendermintUpdatesAllNone(t *testing.T) {
var validators [2]Validator
for i, amt := range amts {
validators[i] = NewValidator(addrs[i], pks[i], Description{})
validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt))
validators[i].PoolShares = NewUnbondedShares(sdk.NewRat(amt))
validators[i].DelegatorShares = sdk.NewRat(amt)
}
@ -475,7 +476,7 @@ func TestGetTendermintUpdatesIdentical(t *testing.T) {
var validators [2]Validator
for i, amt := range amts {
validators[i] = NewValidator(addrs[i], pks[i], Description{})
validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt))
validators[i].PoolShares = NewUnbondedShares(sdk.NewRat(amt))
validators[i].DelegatorShares = sdk.NewRat(amt)
}
validators[0] = keeper.updateValidator(ctx, validators[0])
@ -497,7 +498,7 @@ func TestGetTendermintUpdatesSingleValueChange(t *testing.T) {
var validators [2]Validator
for i, amt := range amts {
validators[i] = NewValidator(addrs[i], pks[i], Description{})
validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt))
validators[i].PoolShares = NewUnbondedShares(sdk.NewRat(amt))
validators[i].DelegatorShares = sdk.NewRat(amt)
}
validators[0] = keeper.updateValidator(ctx, validators[0])
@ -523,7 +524,7 @@ func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) {
var validators [2]Validator
for i, amt := range amts {
validators[i] = NewValidator(addrs[i], pks[i], Description{})
validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt))
validators[i].PoolShares = NewUnbondedShares(sdk.NewRat(amt))
validators[i].DelegatorShares = sdk.NewRat(amt)
}
validators[0] = keeper.updateValidator(ctx, validators[0])
@ -551,7 +552,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) {
var validators [5]Validator
for i, amt := range amts {
validators[i] = NewValidator(addrs[i], pks[i], Description{})
validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt))
validators[i].PoolShares = NewUnbondedShares(sdk.NewRat(amt))
validators[i].DelegatorShares = sdk.NewRat(amt)
}
validators[0] = keeper.updateValidator(ctx, validators[0])
@ -561,7 +562,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) {
// test validtor added at the beginning
// tendermintUpdate set: {} -> {c0}
keeper.updateValidator(ctx, validators[2])
validators[2] = keeper.updateValidator(ctx, validators[2])
updates := keeper.getTendermintUpdates(ctx)
require.Equal(t, 1, len(updates))
require.Equal(t, validators[2].abciValidator(keeper.cdc), updates[0])
@ -569,7 +570,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) {
// test validtor added at the beginning
// tendermintUpdate set: {} -> {c0}
keeper.clearTendermintUpdates(ctx)
keeper.updateValidator(ctx, validators[3])
validators[3] = keeper.updateValidator(ctx, validators[3])
updates = keeper.getTendermintUpdates(ctx)
require.Equal(t, 1, len(updates))
require.Equal(t, validators[3].abciValidator(keeper.cdc), updates[0])
@ -577,7 +578,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) {
// test validtor added at the end
// tendermintUpdate set: {} -> {c0}
keeper.clearTendermintUpdates(ctx)
keeper.updateValidator(ctx, validators[4])
validators[4] = keeper.updateValidator(ctx, validators[4])
updates = keeper.getTendermintUpdates(ctx)
require.Equal(t, 1, len(updates))
require.Equal(t, validators[4].abciValidator(keeper.cdc), updates[0])
@ -593,7 +594,7 @@ func TestGetTendermintUpdatesNotValidatorCliff(t *testing.T) {
var validators [5]Validator
for i, amt := range amts {
validators[i] = NewValidator(addrs[i], pks[i], Description{})
validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt))
validators[i].PoolShares = NewUnbondedShares(sdk.NewRat(amt))
validators[i].DelegatorShares = sdk.NewRat(amt)
}
validators[0] = keeper.updateValidator(ctx, validators[0])
@ -612,7 +613,7 @@ func TestGetTendermintUpdatesNotValidatorCliff(t *testing.T) {
keeper.clearTendermintUpdates(ctx)
assert.Equal(t, 0, len(keeper.getTendermintUpdates(ctx)))
validators[2].PoolShares = NewBondedShares(sdk.NewRat(15))
validators[2].PoolShares = NewUnbondedShares(sdk.NewRat(15))
validators[2] = keeper.updateValidator(ctx, validators[2])
updates = keeper.getTendermintUpdates(ctx)
@ -742,7 +743,7 @@ func TestPool(t *testing.T) {
assert.True(t, expPool.equal(resPool))
//modify a params, save, and retrieve
expPool.TotalSupply = 777
expPool.BondedTokens = 777
keeper.setPool(ctx, expPool)
resPool = keeper.GetPool(ctx)
assert.True(t, expPool.equal(resPool))

View File

@ -8,15 +8,15 @@ import (
// Pool - dynamic parameters of the current state
type Pool struct {
TotalSupply int64 `json:"total_supply"` // total supply of all tokens
UnbondedShares sdk.Rat `json:"unbonded_shares"` // sum of all shares distributed for the Unbonded Pool
UnbondingShares sdk.Rat `json:"unbonding_shares"` // shares moving from Bonded to Unbonded Pool
BondedShares sdk.Rat `json:"bonded_shares"` // sum of all shares distributed for the Bonded Pool
UnbondedTokens int64 `json:"unbonded_pool"` // reserve of unbonded tokens held with validators
UnbondingTokens int64 `json:"unbonding_pool"` // tokens moving from bonded to unbonded pool
BondedTokens int64 `json:"bonded_pool"` // reserve of bonded tokens
InflationLastTime int64 `json:"inflation_last_time"` // block which the last inflation was processed // TODO make time
Inflation sdk.Rat `json:"inflation"` // current annual inflation rate
LooseUnbondedTokens int64 `json:"loose_unbonded_tokens"` // tokens not associated with any validator
UnbondedTokens int64 `json:"unbonded_tokens"` // reserve of unbonded tokens held with validators
UnbondingTokens int64 `json:"unbonding_tokens"` // tokens moving from bonded to unbonded pool
BondedTokens int64 `json:"bonded_tokens"` // reserve of bonded tokens
UnbondedShares sdk.Rat `json:"unbonded_shares"` // sum of all shares distributed for the Unbonded Pool
UnbondingShares sdk.Rat `json:"unbonding_shares"` // shares moving from Bonded to Unbonded Pool
BondedShares sdk.Rat `json:"bonded_shares"` // sum of all shares distributed for the Bonded Pool
InflationLastTime int64 `json:"inflation_last_time"` // block which the last inflation was processed // TODO make time
Inflation sdk.Rat `json:"inflation"` // current annual inflation rate
DateLastCommissionReset int64 `json:"date_last_commission_reset"` // unix timestamp for last commission accounting reset (daily)
@ -33,13 +33,13 @@ func (p Pool) equal(p2 Pool) bool {
// initial pool for testing
func initialPool() Pool {
return Pool{
TotalSupply: 0,
BondedShares: sdk.ZeroRat(),
UnbondingShares: sdk.ZeroRat(),
UnbondedShares: sdk.ZeroRat(),
LooseUnbondedTokens: 0,
BondedTokens: 0,
UnbondingTokens: 0,
UnbondedTokens: 0,
BondedShares: sdk.ZeroRat(),
UnbondingShares: sdk.ZeroRat(),
UnbondedShares: sdk.ZeroRat(),
InflationLastTime: 0,
Inflation: sdk.NewRat(7, 100),
DateLastCommissionReset: 0,
@ -49,10 +49,17 @@ func initialPool() Pool {
//____________________________________________________________________
// Sum total of all staking tokens in the pool
func (p Pool) TokenSupply() int64 {
return p.LooseUnbondedTokens + p.UnbondedTokens + p.UnbondingTokens + p.BondedTokens
}
//____________________________________________________________________
// get the bond ratio of the global state
func (p Pool) bondedRatio() sdk.Rat {
if p.TotalSupply > 0 {
return sdk.NewRat(p.BondedTokens, p.TotalSupply)
if p.TokenSupply() > 0 {
return sdk.NewRat(p.BondedTokens, p.TokenSupply())
}
return sdk.ZeroRat()
}

View File

@ -12,14 +12,15 @@ import (
func TestBondedRatio(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
pool := keeper.GetPool(ctx)
pool.TotalSupply = 3
pool.LooseUnbondedTokens = 1
pool.BondedTokens = 2
// bonded pool / total supply
require.Equal(t, pool.bondedRatio(), sdk.NewRat(2).Quo(sdk.NewRat(3)))
pool.TotalSupply = 0
// avoids divide-by-zero
pool.LooseUnbondedTokens = 0
pool.BondedTokens = 0
require.Equal(t, pool.bondedRatio(), sdk.ZeroRat())
}

View File

@ -46,9 +46,8 @@ func (k Keeper) processProvisions(ctx sdk.Context) Pool {
// more bonded tokens are added proportionally to all validators the only term
// which needs to be updated is the `BondedPool`. So for each previsions cycle:
provisions := pool.Inflation.Mul(sdk.NewRat(pool.TotalSupply)).Quo(hrsPerYrRat).Evaluate()
provisions := pool.Inflation.Mul(sdk.NewRat(pool.TokenSupply())).Quo(hrsPerYrRat).Evaluate()
pool.BondedTokens += provisions
pool.TotalSupply += provisions
return pool
}

View File

@ -1,7 +1,6 @@
package stake
import (
"fmt"
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -20,35 +19,35 @@ func TestGetInflation(t *testing.T) {
// inflationRateChangePerYear = (1- bondedRatio/ GoalBonded) * MaxInflationRateChange
tests := []struct {
name string
setBondedPool, setTotalSupply int64
setInflation, expectedChange sdk.Rat
name string
setBondedTokens, setLooseTokens int64
setInflation, expectedChange sdk.Rat
}{
// with 0% bonded atom supply the inflation should increase by InflationRateChange
{"test 1", 0, 0, sdk.NewRat(7, 100), params.InflationRateChange.Quo(hrsPerYrRat).Round(precision)},
// 100% bonded, starting at 20% inflation and being reduced
// (1 - (1/0.67))*(0.13/8667)
{"test 2", 1, 1, sdk.NewRat(20, 100),
{"test 2", 1, 0, sdk.NewRat(20, 100),
sdk.OneRat().Sub(sdk.OneRat().Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)},
// 50% bonded, starting at 10% inflation and being increased
{"test 3", 1, 2, sdk.NewRat(10, 100),
{"test 3", 1, 1, sdk.NewRat(10, 100),
sdk.OneRat().Sub(sdk.NewRat(1, 2).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)},
// test 7% minimum stop (testing with 100% bonded)
{"test 4", 1, 1, sdk.NewRat(7, 100), sdk.ZeroRat()},
{"test 5", 1, 1, sdk.NewRat(70001, 1000000), sdk.NewRat(-1, 1000000).Round(precision)},
{"test 4", 1, 0, sdk.NewRat(7, 100), sdk.ZeroRat()},
{"test 5", 1, 0, sdk.NewRat(70001, 1000000), sdk.NewRat(-1, 1000000).Round(precision)},
// test 20% maximum stop (testing with 0% bonded)
{"test 6", 0, 0, sdk.NewRat(20, 100), sdk.ZeroRat()},
{"test 7", 0, 0, sdk.NewRat(199999, 1000000), sdk.NewRat(1, 1000000).Round(precision)},
// perfect balance shouldn't change inflation
{"test 8", 67, 100, sdk.NewRat(15, 100), sdk.ZeroRat()},
{"test 8", 67, 33, sdk.NewRat(15, 100), sdk.ZeroRat()},
}
for _, tc := range tests {
pool.BondedTokens, pool.TotalSupply = tc.setBondedPool, tc.setTotalSupply
pool.BondedTokens, pool.LooseUnbondedTokens = tc.setBondedTokens, tc.setLooseTokens
pool.Inflation = tc.setInflation
keeper.setPool(ctx, pool)
@ -67,7 +66,7 @@ func TestProcessProvisions(t *testing.T) {
keeper.setParams(ctx, params)
pool := keeper.GetPool(ctx)
var totalSupply int64 = 550000000
var tokenSupply int64 = 550000000
var bondedShares int64 = 150000000
var unbondedShares int64 = 400000000
@ -75,10 +74,11 @@ func TestProcessProvisions(t *testing.T) {
var validators [5]Validator
validators[0] = NewValidator(addrs[0], pks[0], Description{})
validators[0], pool, _ = validators[0].addTokensFromDel(pool, 150000000)
validators[0] = keeper.updateValidator(ctx, validators[0])
keeper.setPool(ctx, pool)
assert.Equal(t, bondedShares, pool.BondedTokens, "%v", pool)
fmt.Printf("debug pool: %v validator: %v\n", pool, validators[0])
validators[0] = keeper.updateValidator(ctx, validators[0])
pool = keeper.GetPool(ctx)
require.Equal(t, bondedShares, pool.BondedTokens, "%v", pool)
validators[1] = NewValidator(addrs[1], pks[1], Description{})
validators[1], pool, _ = validators[1].addTokensFromDel(pool, 100000000)
keeper.setPool(ctx, pool)
@ -96,45 +96,42 @@ func TestProcessProvisions(t *testing.T) {
keeper.setPool(ctx, pool)
validators[4] = keeper.updateValidator(ctx, validators[4])
validator, _ := keeper.GetValidator(ctx, addrs[0])
fmt.Printf("debug validators[0]: %v\n", validator)
assert.Equal(t, totalSupply, pool.TotalSupply)
assert.Equal(t, tokenSupply, pool.TokenSupply())
assert.Equal(t, bondedShares, pool.BondedTokens)
assert.Equal(t, unbondedShares, pool.UnbondedTokens)
// initial bonded ratio ~ 27%
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(bondedShares, totalSupply)), "%v", pool.bondedRatio())
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(bondedShares, tokenSupply)), "%v", pool.bondedRatio())
// test the value of validator shares
assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat()), "%v", pool.bondedShareExRate())
initialSupply := pool.TotalSupply
initialUnbonded := pool.TotalSupply - pool.BondedTokens
initialSupply := pool.TokenSupply()
initialUnbonded := pool.TokenSupply() - pool.BondedTokens
// process the provisions a year
for hr := 0; hr < 8766; hr++ {
pool := keeper.GetPool(ctx)
expInflation := keeper.nextInflation(ctx).Round(1000000000)
expProvisions := (expInflation.Mul(sdk.NewRat(pool.TotalSupply)).Quo(hrsPerYrRat)).Evaluate()
startBondedPool := pool.BondedTokens
startTotalSupply := pool.TotalSupply
expProvisions := (expInflation.Mul(sdk.NewRat(pool.TokenSupply())).Quo(hrsPerYrRat)).Evaluate()
startBondedTokens := pool.BondedTokens
startTotalSupply := pool.TokenSupply()
pool = keeper.processProvisions(ctx)
keeper.setPool(ctx, pool)
//fmt.Printf("hr %v, startBondedPool %v, expProvisions %v, pool.BondedTokens %v\n", hr, startBondedPool, expProvisions, pool.BondedTokens)
require.Equal(t, startBondedPool+expProvisions, pool.BondedTokens, "hr %v", hr)
require.Equal(t, startTotalSupply+expProvisions, pool.TotalSupply)
//fmt.Printf("hr %v, startBondedTokens %v, expProvisions %v, pool.BondedTokens %v\n", hr, startBondedTokens, expProvisions, pool.BondedTokens)
require.Equal(t, startBondedTokens+expProvisions, pool.BondedTokens, "hr %v", hr)
require.Equal(t, startTotalSupply+expProvisions, pool.TokenSupply())
}
pool = keeper.GetPool(ctx)
assert.NotEqual(t, initialSupply, pool.TotalSupply)
assert.NotEqual(t, initialSupply, pool.TokenSupply())
assert.Equal(t, initialUnbonded, pool.UnbondedTokens)
//panic(fmt.Sprintf("debug total %v, bonded %v, diff %v\n", p.TotalSupply, p.BondedTokens, pool.TotalSupply-pool.BondedTokens))
//panic(fmt.Sprintf("debug total %v, bonded %v, diff %v\n", p.TotalSupply, p.BondedTokens, pool.TokenSupply()-pool.BondedTokens))
// initial bonded ratio ~ from 27% to 40% increase for bonded holders ownership of total supply
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(211813022, 611813022)), "%v", pool.bondedRatio())
// global supply
assert.Equal(t, int64(611813022), pool.TotalSupply)
assert.Equal(t, int64(611813022), pool.TokenSupply())
assert.Equal(t, int64(211813022), pool.BondedTokens)
assert.Equal(t, unbondedShares, pool.UnbondedTokens)

View File

@ -96,7 +96,6 @@ func TestRemoveShares(t *testing.T) {
DelegatorShares: delShares,
}
pool := Pool{
TotalSupply: 0,
BondedShares: sdk.NewRat(248305),
UnbondedShares: sdk.NewRat(232147),
BondedTokens: 248305,
@ -136,7 +135,7 @@ func TestUpdateStatus(t *testing.T) {
assert.Equal(t, int64(100), pool.UnbondingTokens)
assert.Equal(t, int64(0), pool.UnbondedTokens)
val, pool = val.UpdateStatus(pool, sdk.Unbonded)
val, pool = val.UpdateStatus(pool, sdk.Bonded)
assert.Equal(t, int64(100), val.PoolShares.Bonded().Evaluate())
assert.Equal(t, int64(0), val.PoolShares.Unbonding().Evaluate())
assert.Equal(t, int64(0), val.PoolShares.Unbonded().Evaluate())
@ -329,7 +328,6 @@ func TestPossibleOverflow(t *testing.T) {
DelegatorShares: delShares,
}
pool := Pool{
TotalSupply: 0,
BondedShares: poolShares,
UnbondedShares: sdk.ZeroRat(),
BondedTokens: poolShares.Evaluate(),

View File

@ -20,7 +20,7 @@ func TestViewSlashBond(t *testing.T) {
validators[i] = Validator{
Owner: addrVals[i],
PubKey: pks[i],
PoolShares: NewBondedShares(sdk.NewRat(amt)),
PoolShares: NewUnbondedShares(sdk.NewRat(amt)),
DelegatorShares: sdk.NewRat(amt),
}
}