fix tick tests
This commit is contained in:
parent
5486d6a283
commit
c1a8f2cce9
|
@ -4,7 +4,29 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
//TODO make these next two functions more efficient should be reading and writting to state ye know
|
||||
// get the bond ratio of the global state
|
||||
func (p Pool) bondedRatio() sdk.Rat {
|
||||
if p.TotalSupply > 0 {
|
||||
return sdk.NewRat(p.BondedPool, p.TotalSupply)
|
||||
}
|
||||
return sdk.ZeroRat
|
||||
}
|
||||
|
||||
// get the exchange rate of bonded token per issued share
|
||||
func (p Pool) bondedShareExRate() sdk.Rat {
|
||||
if p.BondedShares.IsZero() {
|
||||
return sdk.OneRat
|
||||
}
|
||||
return sdk.NewRat(p.BondedPool).Quo(p.BondedShares)
|
||||
}
|
||||
|
||||
// get the exchange rate of unbonded tokens held in candidates per issued share
|
||||
func (p Pool) unbondedShareExRate() sdk.Rat {
|
||||
if p.UnbondedShares.IsZero() {
|
||||
return sdk.OneRat
|
||||
}
|
||||
return sdk.NewRat(p.UnbondedPool).Quo(p.UnbondedShares)
|
||||
}
|
||||
|
||||
// move a candidates asset pool from bonded to unbonded pool
|
||||
func (p Pool) bondedToUnbondedPool(candidate Candidate) (Pool, Candidate) {
|
||||
|
@ -62,8 +84,6 @@ func (p Pool) removeSharesUnbonded(shares sdk.Rat) (p2 Pool, removedTokens int64
|
|||
func (p Pool) candidateAddTokens(candidate Candidate,
|
||||
amount int64) (p2 Pool, candidate2 Candidate, issuedDelegatorShares sdk.Rat) {
|
||||
|
||||
exRate := candidate.delegatorShareExRate()
|
||||
|
||||
var receivedGlobalShares sdk.Rat
|
||||
if candidate.Status == Bonded {
|
||||
p, receivedGlobalShares = p.addTokensBonded(amount)
|
||||
|
@ -72,8 +92,10 @@ func (p Pool) candidateAddTokens(candidate Candidate,
|
|||
}
|
||||
candidate.Assets = candidate.Assets.Add(receivedGlobalShares)
|
||||
|
||||
exRate := candidate.delegatorShareExRate()
|
||||
issuedDelegatorShares = exRate.Mul(receivedGlobalShares)
|
||||
candidate.Liabilities = candidate.Liabilities.Add(issuedDelegatorShares)
|
||||
|
||||
return p, candidate, issuedDelegatorShares
|
||||
}
|
||||
|
||||
|
|
|
@ -124,12 +124,11 @@ func createTestInput(t *testing.T, sender sdk.Address, isCheckTx bool, initCoins
|
|||
ck := bank.NewCoinKeeper(accountMapper)
|
||||
keeper := NewKeeper(ctx, cdc, keyStake, ck)
|
||||
|
||||
//params := paramsNoInflation()
|
||||
params := keeper.GetParams(ctx)
|
||||
|
||||
// fill all the addresses with some coins
|
||||
for _, addr := range addrs {
|
||||
ck.AddCoins(ctx, addr, sdk.Coins{{params.BondDenom, initCoins}})
|
||||
ck.AddCoins(ctx, addr, sdk.Coins{
|
||||
{keeper.GetParams(ctx).BondDenom, initCoins},
|
||||
})
|
||||
}
|
||||
|
||||
return ctx, accountMapper, keeper
|
||||
|
|
|
@ -2,39 +2,35 @@ package stake
|
|||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
abci "github.com/tendermint/abci/types"
|
||||
)
|
||||
|
||||
const (
|
||||
hrsPerYear = 8766 // as defined by a julian year of 365.25 days
|
||||
precision = 1000000000
|
||||
hrsPerYr = 8766 // as defined by a julian year of 365.25 days
|
||||
precision = 1000000000
|
||||
)
|
||||
|
||||
var hrsPerYrRat = sdk.NewRat(hrsPerYear) // as defined by a julian year of 365.25 days
|
||||
var hrsPerYrRat = sdk.NewRat(hrsPerYr) // as defined by a julian year of 365.25 days
|
||||
|
||||
// Tick - called at the end of every block
|
||||
func (k Keeper) Tick(ctx sdk.Context) (change []*abci.Validator, err error) {
|
||||
|
||||
// retrieve params
|
||||
func (k Keeper) Tick(ctx sdk.Context) (change []Validator) {
|
||||
p := k.GetPool(ctx)
|
||||
height := ctx.BlockHeight()
|
||||
|
||||
// Process Validator Provisions
|
||||
// XXX right now just process every 5 blocks, in new SDK make hourly
|
||||
if p.InflationLastTime+5 <= height {
|
||||
p.InflationLastTime = height
|
||||
k.processProvisions(ctx)
|
||||
blockTime := ctx.BlockHeader().Time // XXX assuming in seconds, confirm
|
||||
if p.InflationLastTime+blockTime >= 3600 {
|
||||
p.InflationLastTime = blockTime
|
||||
p = k.processProvisions(ctx)
|
||||
}
|
||||
|
||||
newVals := k.GetValidators(ctx)
|
||||
// save the params
|
||||
k.setPool(ctx, p)
|
||||
|
||||
// XXX determine change from old validators, set to change
|
||||
_ = newVals
|
||||
return change, nil
|
||||
change = k.getAccUpdateValidators(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
// process provisions for an hour period
|
||||
func (k Keeper) processProvisions(ctx sdk.Context) {
|
||||
func (k Keeper) processProvisions(ctx sdk.Context) Pool {
|
||||
|
||||
pool := k.GetPool(ctx)
|
||||
pool.Inflation = k.nextInflation(ctx).Round(precision)
|
||||
|
@ -46,9 +42,7 @@ func (k Keeper) processProvisions(ctx sdk.Context) {
|
|||
provisions := pool.Inflation.Mul(sdk.NewRat(pool.TotalSupply)).Quo(hrsPerYrRat).Evaluate()
|
||||
pool.BondedPool += provisions
|
||||
pool.TotalSupply += provisions
|
||||
|
||||
// save the params
|
||||
k.setPool(ctx, pool)
|
||||
return pool
|
||||
}
|
||||
|
||||
// get the next inflation rate for the hour
|
||||
|
|
|
@ -1,116 +1,132 @@
|
|||
package stake
|
||||
|
||||
//import (
|
||||
//"testing"
|
||||
import (
|
||||
"testing"
|
||||
|
||||
//sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
//"github.com/stretchr/testify/assert"
|
||||
//)
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
//func TestGetInflation(t *testing.T) {
|
||||
//ctx, _, keeper := createTestInput(t, nil, false, 0)
|
||||
//params := defaultParams()
|
||||
//keeper.setParams(ctx, params)
|
||||
//gs := keeper.GetPool(ctx)
|
||||
func TestGetInflation(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, nil, false, 0)
|
||||
pool := keeper.GetPool(ctx)
|
||||
params := keeper.GetParams(ctx)
|
||||
hrsPerYrRat := sdk.NewRat(hrsPerYr)
|
||||
|
||||
//// Governing Mechanism:
|
||||
//// bondedRatio = BondedPool / TotalSupply
|
||||
//// inflationRateChangePerYear = (1- bondedRatio/ GoalBonded) * MaxInflationRateChange
|
||||
// Governing Mechanism:
|
||||
// bondedRatio = BondedPool / TotalSupply
|
||||
// inflationRateChangePerYear = (1- bondedRatio/ GoalBonded) * MaxInflationRateChange
|
||||
|
||||
//tests := []struct {
|
||||
//setBondedPool, setTotalSupply int64
|
||||
//setInflation, expectedChange sdk.Rat
|
||||
//}{
|
||||
//// with 0% bonded atom supply the inflation should increase by InflationRateChange
|
||||
//{0, 0, sdk.NewRat(7, 100), params.InflationRateChange.Quo(hrsPerYr)},
|
||||
tests := []struct {
|
||||
name string
|
||||
setBondedPool, setTotalSupply 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)},
|
||||
|
||||
//// 100% bonded, starting at 20% inflation and being reduced
|
||||
//{1, 1, sdk.NewRat(20, 100), sdk.OneRat.Sub(sdk.OneRat.Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYr)},
|
||||
// 100% bonded, starting at 20% inflation and being reduced
|
||||
// (1 - (1/0.67))*(0.13/8667)
|
||||
{"test 2", 1, 1, sdk.NewRat(20, 100), sdk.OneRat.Sub(sdk.OneRat.Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat)},
|
||||
|
||||
//// 50% bonded, starting at 10% inflation and being increased
|
||||
//{1, 2, sdk.NewRat(10, 100), sdk.OneRat.Sub(sdk.NewRat(1, 2).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYr)},
|
||||
// 50% bonded, starting at 10% inflation and being increased
|
||||
{"test 3", 1, 2, sdk.NewRat(10, 100), sdk.OneRat.Sub(sdk.NewRat(1, 2).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat)},
|
||||
|
||||
//// test 7% minimum stop (testing with 100% bonded)
|
||||
//{1, 1, sdk.NewRat(7, 100), sdk.ZeroRat},
|
||||
//{1, 1, sdk.NewRat(70001, 1000000), sdk.NewRat(-1, 1000000)},
|
||||
// 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)},
|
||||
|
||||
//// test 20% maximum stop (testing with 0% bonded)
|
||||
//{0, 0, sdk.NewRat(20, 100), sdk.ZeroRat},
|
||||
//{0, 0, sdk.NewRat(199999, 1000000), sdk.NewRat(1, 1000000)},
|
||||
// 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)},
|
||||
|
||||
//// perfect balance shouldn't change inflation
|
||||
//{67, 100, sdk.NewRat(15, 100), sdk.ZeroRat},
|
||||
//}
|
||||
//for _, tc := range tests {
|
||||
//gs.BondedPool, p.TotalSupply = tc.setBondedPool, tc.setTotalSupply
|
||||
//gs.Inflation = tc.setInflation
|
||||
// perfect balance shouldn't change inflation
|
||||
{"test 8", 67, 100, sdk.NewRat(15, 100), sdk.ZeroRat},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
pool.BondedPool, pool.TotalSupply = tc.setBondedPool, tc.setTotalSupply
|
||||
pool.Inflation = tc.setInflation
|
||||
keeper.setPool(ctx, pool)
|
||||
|
||||
//inflation := nextInflation(gs, params)
|
||||
//diffInflation := inflation.Sub(tc.setInflation)
|
||||
inflation := keeper.nextInflation(ctx)
|
||||
diffInflation := inflation.Sub(tc.setInflation)
|
||||
|
||||
//assert.True(t, diffInflation.Equal(tc.expectedChange),
|
||||
//"%v, %v", diffInflation, tc.expectedChange)
|
||||
//}
|
||||
//}
|
||||
assert.True(t, diffInflation.Equal(tc.expectedChange),
|
||||
"Name: %v\nDiff: %v\nExpected: %v\n", tc.name, diffInflation, tc.expectedChange)
|
||||
}
|
||||
}
|
||||
|
||||
//func TestProcessProvisions(t *testing.T) {
|
||||
//ctx, _, keeper := createTestInput(t, nil, false, 0)
|
||||
//params := defaultParams()
|
||||
//keeper.setParams(ctx, params)
|
||||
//gs := keeper.GetPool(ctx)
|
||||
func TestProcessProvisions(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, nil, false, 0)
|
||||
params := defaultParams()
|
||||
keeper.setParams(ctx, params)
|
||||
pool := keeper.GetPool(ctx)
|
||||
|
||||
//// create some candidates some bonded, some unbonded
|
||||
//candidates := candidatesFromAddrsEmpty(addrs)
|
||||
//for i, candidate := range candidates {
|
||||
//if i < 5 {
|
||||
//candidate.Status = Bonded
|
||||
//}
|
||||
//mintedTokens := int64((i + 1) * 10000000)
|
||||
//gs.TotalSupply += mintedTokens
|
||||
//keeper.candidateAddTokens(ctx, candidate, mintedTokens)
|
||||
//keeper.setCandidate(ctx, candidate)
|
||||
//}
|
||||
//var totalSupply int64 = 550000000
|
||||
//var bondedShares int64 = 150000000
|
||||
//var unbondedShares int64 = 400000000
|
||||
// create some candidates some bonded, some unbonded
|
||||
candidates := make([]Candidate, 10)
|
||||
for i := 0; i < 10; i++ {
|
||||
c := Candidate{
|
||||
Status: Unbonded,
|
||||
PubKey: pks[i],
|
||||
Address: addrs[i],
|
||||
Assets: sdk.NewRat(0),
|
||||
Liabilities: sdk.NewRat(0),
|
||||
}
|
||||
if i < 5 {
|
||||
c.Status = Bonded
|
||||
}
|
||||
mintedTokens := int64((i + 1) * 10000000)
|
||||
pool.TotalSupply += mintedTokens
|
||||
pool, c, _ = pool.candidateAddTokens(c, mintedTokens)
|
||||
|
||||
//// initial bonded ratio ~ 27%
|
||||
//assert.True(t, p.bondedRatio().Equal(sdk.NewRat(bondedShares, totalSupply)), "%v", p.bondedRatio())
|
||||
keeper.setCandidate(ctx, c)
|
||||
candidates[i] = c
|
||||
}
|
||||
keeper.setPool(ctx, pool)
|
||||
var totalSupply int64 = 550000000
|
||||
var bondedShares int64 = 150000000
|
||||
var unbondedShares int64 = 400000000
|
||||
assert.Equal(t, totalSupply, pool.TotalSupply)
|
||||
assert.Equal(t, bondedShares, pool.BondedPool)
|
||||
assert.Equal(t, unbondedShares, pool.UnbondedPool)
|
||||
|
||||
//// Supplies
|
||||
//assert.Equal(t, totalSupply, p.TotalSupply)
|
||||
//assert.Equal(t, bondedShares, p.BondedPool)
|
||||
//assert.Equal(t, unbondedShares, p.UnbondedPool)
|
||||
// initial bonded ratio ~ 27%
|
||||
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(bondedShares, totalSupply)), "%v", pool.bondedRatio())
|
||||
|
||||
//// test the value of candidate shares
|
||||
//assert.True(t, p.bondedShareExRate().Equal(sdk.OneRat), "%v", p.bondedShareExRate())
|
||||
// test the value of candidate shares
|
||||
assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat), "%v", pool.bondedShareExRate())
|
||||
|
||||
//initialSupply := p.TotalSupply
|
||||
//initialUnbonded := p.TotalSupply - p.BondedPool
|
||||
initialSupply := pool.TotalSupply
|
||||
initialUnbonded := pool.TotalSupply - pool.BondedPool
|
||||
|
||||
//// process the provisions a year
|
||||
//for hr := 0; hr < 8766; hr++ {
|
||||
//expInflation := nextInflation(gs, params).Round(1000000000)
|
||||
//expProvisions := (expInflation.Mul(sdk.NewRat(gs.TotalSupply)).Quo(hrsPerYr)).Evaluate()
|
||||
//startBondedPool := p.BondedPool
|
||||
//startTotalSupply := p.TotalSupply
|
||||
//processProvisions(ctx, keeper, p, params)
|
||||
//assert.Equal(t, startBondedPool+expProvisions, p.BondedPool)
|
||||
//assert.Equal(t, startTotalSupply+expProvisions, p.TotalSupply)
|
||||
//}
|
||||
//assert.NotEqual(t, initialSupply, p.TotalSupply)
|
||||
//assert.Equal(t, initialUnbonded, p.UnbondedPool)
|
||||
////panic(fmt.Sprintf("debug total %v, bonded %v, diff %v\n", p.TotalSupply, p.BondedPool, p.TotalSupply-gs.BondedPool))
|
||||
// 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.BondedPool
|
||||
startTotalSupply := pool.TotalSupply
|
||||
pool = keeper.processProvisions(ctx)
|
||||
keeper.setPool(ctx, pool)
|
||||
//fmt.Printf("hr %v, startBondedPool %v, expProvisions %v, pool.BondedPool %v\n", hr, startBondedPool, expProvisions, pool.BondedPool)
|
||||
require.Equal(t, startBondedPool+expProvisions, pool.BondedPool, "hr %v", hr)
|
||||
require.Equal(t, startTotalSupply+expProvisions, pool.TotalSupply)
|
||||
}
|
||||
pool = keeper.GetPool(ctx)
|
||||
assert.NotEqual(t, initialSupply, pool.TotalSupply)
|
||||
assert.Equal(t, initialUnbonded, pool.UnbondedPool)
|
||||
//panic(fmt.Sprintf("debug total %v, bonded %v, diff %v\n", p.TotalSupply, p.BondedPool, pool.TotalSupply-pool.BondedPool))
|
||||
|
||||
//// initial bonded ratio ~ 35% ~ 30% increase for bonded holders
|
||||
//assert.True(t, p.bondedRatio().Equal(sdk.NewRat(105906511, 305906511)), "%v", p.bondedRatio())
|
||||
// initial bonded ratio ~ from 27% to 40% increase for bonded holders ownership of total supply
|
||||
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(271734723, 671734723)), "%v", pool.bondedRatio())
|
||||
|
||||
//// global supply
|
||||
//assert.Equal(t, int64(611813022), p.TotalSupply)
|
||||
//assert.Equal(t, int64(211813022), p.BondedPool)
|
||||
//assert.Equal(t, unbondedShares, p.UnbondedPool)
|
||||
// global supply
|
||||
assert.Equal(t, int64(671734723), pool.TotalSupply)
|
||||
assert.Equal(t, int64(271734723), pool.BondedPool)
|
||||
assert.Equal(t, unbondedShares, pool.UnbondedPool)
|
||||
|
||||
//// test the value of candidate shares
|
||||
//assert.True(t, p.bondedShareExRate().Mul(sdk.NewRat(bondedShares)).Equal(sdk.NewRat(211813022)), "%v", p.bondedShareExRate())
|
||||
// test the value of candidate shares
|
||||
assert.True(t, pool.bondedShareExRate().Mul(sdk.NewRat(bondedShares)).Equal(sdk.NewRat(271734723)), "%v", pool.bondedShareExRate())
|
||||
|
||||
//}
|
||||
}
|
||||
|
|
|
@ -42,8 +42,6 @@ type Pool struct {
|
|||
Inflation sdk.Rat `json:"inflation"` // current annual inflation rate
|
||||
}
|
||||
|
||||
// XXX define globalstate interface?
|
||||
|
||||
func initialPool() Pool {
|
||||
return Pool{
|
||||
TotalSupply: 0,
|
||||
|
@ -56,30 +54,6 @@ func initialPool() Pool {
|
|||
}
|
||||
}
|
||||
|
||||
// get the bond ratio of the global state
|
||||
func (p Pool) bondedRatio() sdk.Rat {
|
||||
if p.TotalSupply > 0 {
|
||||
return sdk.NewRat(p.BondedPool, p.TotalSupply)
|
||||
}
|
||||
return sdk.ZeroRat
|
||||
}
|
||||
|
||||
// get the exchange rate of bonded token per issued share
|
||||
func (p Pool) bondedShareExRate() sdk.Rat {
|
||||
if p.BondedShares.IsZero() {
|
||||
return sdk.OneRat
|
||||
}
|
||||
return sdk.NewRat(p.BondedPool).Quo(p.BondedShares)
|
||||
}
|
||||
|
||||
// get the exchange rate of unbonded tokens held in candidates per issued share
|
||||
func (p Pool) unbondedShareExRate() sdk.Rat {
|
||||
if p.UnbondedShares.IsZero() {
|
||||
return sdk.OneRat
|
||||
}
|
||||
return sdk.NewRat(p.UnbondedPool).Quo(p.UnbondedShares)
|
||||
}
|
||||
|
||||
//_______________________________________________________________________________________________________
|
||||
|
||||
// CandidateStatus - status of a validator-candidate
|
||||
|
|
Loading…
Reference in New Issue