expose some keeper functions, tick cleanup

This commit is contained in:
rigelrozanski 2018-03-22 18:10:25 +01:00
parent 3a011678e7
commit 5ba297089a
10 changed files with 80 additions and 73 deletions

View File

@ -24,7 +24,7 @@ func validatorCommand() *cobra.Command {
return cmd
}
func getValidators(height *int64) ([]byte, error) {
func GetValidators(height *int64) ([]byte, error) {
// get the node
node, err := client.GetNode()
if err != nil {
@ -59,7 +59,7 @@ func printValidators(cmd *cobra.Command, args []string) error {
}
}
output, err := getValidators(height)
output, err := GetValidators(height)
if err != nil {
return err
}
@ -84,7 +84,7 @@ func ValidatorsetRequestHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ERROR: Requested block height is bigger then the chain length."))
return
}
output, err := getValidators(&height)
output, err := GetValidators(&height)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
@ -100,7 +100,7 @@ func LatestValidatorsetRequestHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(err.Error()))
return
}
output, err := getValidators(&height)
output, err := GetValidators(&height)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))

View File

@ -19,7 +19,7 @@ const (
// separated for testing
//func InitState(ctx sdk.Context, k Keeper, key, value string) sdk.Error {
//params := k.getParams(ctx)
//params := k.GetParams(ctx)
//switch key {
//case "allowed_bond_denom":
//params.BondDenom = value
@ -88,11 +88,11 @@ func NewHandler(k Keeper, ck bank.CoinKeeper) sdk.Handler {
func (k Keeper) handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy) sdk.Result {
// check to see if the pubkey or sender has been registered before
_, found := k.getCandidate(ctx, msg.CandidateAddr)
_, found := k.GetCandidate(ctx, msg.CandidateAddr)
if found {
return ErrCandidateExistsAddr().Result()
}
if msg.Bond.Denom != k.getParams(ctx).BondDenom {
if msg.Bond.Denom != k.GetParams(ctx).BondDenom {
return ErrBadBondingDenom().Result()
}
if ctx.IsCheckTx() {
@ -112,7 +112,7 @@ func (k Keeper) handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandida
func (k Keeper) handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy) sdk.Result {
// candidate must already be registered
candidate, found := k.getCandidate(ctx, msg.CandidateAddr)
candidate, found := k.GetCandidate(ctx, msg.CandidateAddr)
if !found {
return ErrBadCandidateAddr().Result()
}
@ -146,11 +146,11 @@ func (k Keeper) handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy) sd
func (k Keeper) handleMsgDelegate(ctx sdk.Context, msg MsgDelegate) sdk.Result {
candidate, found := k.getCandidate(ctx, msg.CandidateAddr)
candidate, found := k.GetCandidate(ctx, msg.CandidateAddr)
if !found {
return ErrBadCandidateAddr().Result()
}
if msg.Bond.Denom != k.getParams(ctx).BondDenom {
if msg.Bond.Denom != k.GetParams(ctx).BondDenom {
return ErrBadBondingDenom().Result()
}
if ctx.IsCheckTx() {
@ -250,7 +250,7 @@ func (k Keeper) handleMsgUnbond(ctx sdk.Context, msg MsgUnbond) sdk.Result {
bond.Shares = bond.Shares.Sub(shares)
// get pubKey candidate
candidate, found := k.getCandidate(ctx, msg.CandidateAddr)
candidate, found := k.GetCandidate(ctx, msg.CandidateAddr)
if !found {
return ErrNoCandidateForAddress().Result()
}
@ -273,7 +273,7 @@ func (k Keeper) handleMsgUnbond(ctx sdk.Context, msg MsgUnbond) sdk.Result {
// Add the coins
returnAmount := k.candidateRemoveShares(ctx, candidate, shares)
returnCoins := sdk.Coins{{k.getParams(ctx).BondDenom, returnAmount}}
returnCoins := sdk.Coins{{k.GetParams(ctx).BondDenom, returnAmount}}
k.coinKeeper.AddCoins(ctx, bond.DelegatorAddr, returnCoins)
// lastly if an revoke candidate if necessary
@ -308,7 +308,7 @@ func (k Keeper) UnbondCoins(ctx sdk.Context, bond DelegatorBond, candidate Candi
bond.Shares = bond.Shares.Sub(shares)
returnAmount := k.candidateRemoveShares(ctx, candidate, shares)
returnCoins := sdk.Coins{{k.getParams(ctx).BondDenom, returnAmount}}
returnCoins := sdk.Coins{{k.GetParams(ctx).BondDenom, returnAmount}}
_, err := k.coinKeeper.AddCoins(ctx, candidate.Address, returnCoins)
if err != nil {

View File

@ -68,7 +68,7 @@ package stake
//assert.NoError(t, got, "expected msg %d to be ok, got %v", i, got)
////Check that the accounts and the bond account have the appropriate values
//candidates := mapper.getCandidates()
//candidates := mapper.GetCandidates()
//expectedBond += bondAmount
////expectedSender := initSender - expectedBond
//gotBonded := candidates[0].Liabilities.Evaluate()
@ -97,7 +97,7 @@ package stake
//assert.NoError(t, got, "expected msg %d to be ok, got %v", i, got)
////Check that the accounts and the bond account have the appropriate values
//candidates := mapper.getCandidates()
//candidates := mapper.GetCandidates()
//expectedBond := initBond - int64(i+1)*unbondShares // +1 since we send 1 at the start of loop
////expectedSender := initSender + (initBond - expectedBond)
//gotBonded := candidates[0].Liabilities.Evaluate()
@ -148,7 +148,7 @@ package stake
//assert.NoError(t, got, "expected msg %d to be ok, got %v", i, got)
////Check that the account is bonded
//candidates := mapper.getCandidates()
//candidates := mapper.GetCandidates()
//require.Equal(t, i, len(candidates))
//val := candidates[i]
//balanceExpd := initSender - 10
@ -160,17 +160,17 @@ package stake
//// unbond them all
//for i, addr := range addrs {
//candidatePre := mapper.getCandidate(addrs[i])
//candidatePre := mapper.GetCandidate(addrs[i])
//msgUndelegate := NewMsgUnbond(addrs[i], "10")
//deliverer.sender = addr
//got := deliverer.unbond(msgUndelegate)
//assert.NoError(t, got, "expected msg %d to be ok, got %v", i, got)
////Check that the account is unbonded
//candidates := mapper.getCandidates()
//candidates := mapper.GetCandidates()
//assert.Equal(t, len(addrs)-(i+1), len(candidates), "expected %d candidates got %d", len(addrs)-(i+1), len(candidates))
//candidatePost := mapper.getCandidate(addrs[i])
//candidatePost := mapper.GetCandidate(addrs[i])
//balanceExpd := initSender
//balanceGot := accStore.GetAccount(ctx, candidatePre.Address).GetCoins()
//assert.Nil(t, candidatePost, "expected nil candidate retrieve, got %d", 0, candidatePost)

View File

@ -28,7 +28,8 @@ func NewKeeper(ctx sdk.Context, cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinK
//_________________________________________________________________________
func (k Keeper) getCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candidate, found bool) {
// get a single candidate
func (k Keeper) GetCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candidate, found bool) {
store := ctx.KVStore(k.storeKey)
b := store.Get(GetCandidateKey(addr))
if b == nil {
@ -61,7 +62,8 @@ func (k Keeper) removeCandidate(ctx sdk.Context, candidateAddr sdk.Address) {
store.Delete(GetCandidateKey(candidateAddr))
}
func (k Keeper) getCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Candidates) {
// Get the set of all candidates, retrieve a maxRetrieve number of records
func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Candidates) {
store := ctx.KVStore(k.storeKey)
iterator := store.Iterator(subspace(CandidateKeyPrefix))
@ -116,7 +118,7 @@ func (k Keeper) removeValidator(ctx sdk.Context, address sdk.Address) {
store.Set(GetValidatorUpdatesKey(address), b)
// now actually delete from the validator set
candidate, found := k.getCandidate(ctx, address)
candidate, found := k.GetCandidate(ctx, address)
if found {
store.Delete(GetValidatorKey(address, candidate.VotingPower, k.cdc))
}
@ -125,14 +127,15 @@ func (k Keeper) removeValidator(ctx sdk.Context, address sdk.Address) {
// get the most recent updated validator set from the Candidates. These bonds
// are already sorted by VotingPower from the UpdateVotingPower function which
// is the only function which is to modify the VotingPower
func (k Keeper) getValidators(ctx sdk.Context, maxVal uint16) (validators []Validator) {
func (k Keeper) GetValidators(ctx sdk.Context) (validators []Validator) {
store := ctx.KVStore(k.storeKey)
maxVal := k.GetParams(ctx).MaxValidators
iterator := store.Iterator(subspace(ValidatorKeyPrefix)) //smallest to largest
validators = make([]Validator, maxVal)
for i := 0; ; i++ {
i := 0
for ; ; i++ {
if !iterator.Valid() || i > int(maxVal-1) {
iterator.Close()
break
@ -146,7 +149,7 @@ func (k Keeper) getValidators(ctx sdk.Context, maxVal uint16) (validators []Vali
validators[i] = val
iterator.Next()
}
return
return validators[:i] // trim
}
//_________________________________________________________________________
@ -241,7 +244,7 @@ func (k Keeper) getDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRet
//_______________________________________________________________________
// load/save the global staking params
func (k Keeper) getParams(ctx sdk.Context) (params Params) {
func (k Keeper) GetParams(ctx sdk.Context) (params Params) {
// check if cached before anything
if k.params != (Params{}) {
return k.params

View File

@ -18,8 +18,8 @@ import (
//func TestUpdateVotingPower(t *testing.T) {
//assert := assert.New(t)
//store := initTestStore(t)
//params := getParams(store)
//gs := getPool(store)
//params := GetParams(store)
//gs := GetPool(store)
//N := 5
//actors := newAddrs(N)
@ -118,7 +118,7 @@ import (
//testRemove(t, vs1[1], changed[0])
//testRemove(t, vs1[2], changed[1])
//// test many sdk of changes //vs2 = []Validator{v1, v3, v4, v5} //vs2[2].VotingPower = sdk.NewRat(11) //changed = vs1.validatorsUpdated(vs2) //require.Equal(4, len(changed), "%v", changed) // change 1, remove 1, add 2 //testRemove(t, vs1[1], changed[0]) //testChange(t, vs2[1], changed[1]) //testChange(t, vs2[2], changed[2]) //testChange(t, vs2[3], changed[3]) //} //func TestUpdateValidatorSet(t *testing.T) { //assert, require := assert.New(t), require.New(t) //store := initTestStore(t) //params := getParams(store) //gs := getPool(store) //N := 5
//// test many sdk of changes //vs2 = []Validator{v1, v3, v4, v5} //vs2[2].VotingPower = sdk.NewRat(11) //changed = vs1.validatorsUpdated(vs2) //require.Equal(4, len(changed), "%v", changed) // change 1, remove 1, add 2 //testRemove(t, vs1[1], changed[0]) //testChange(t, vs2[1], changed[1]) //testChange(t, vs2[2], changed[2]) //testChange(t, vs2[3], changed[3]) //} //func TestUpdateValidatorSet(t *testing.T) { //assert, require := assert.New(t), require.New(t) //store := initTestStore(t) //params := GetParams(store) //gs := GetPool(store) //N := 5
//actors := newAddrs(N)
//candidates := candidatesFromActors(actors, []int64{400, 200, 100, 10, 1})
//for _, c := range candidates {
@ -137,7 +137,7 @@ import (
//require.Nil(err)
//require.Equal(1, len(change), "%v", change)
//testRemove(t, candidates[4].validator(), change[0])
//candidates = getCandidates(store)
//candidates = GetCandidates(store)
//assert.Equal(int64(0), candidates[4].VotingPower.Evaluate())
//// mess with the power's of the candidates and test
@ -152,7 +152,7 @@ import (
//change, err = UpdateValidatorSet(store, p, params)
//require.Nil(err)
//require.Equal(5, len(change), "%v", change) // 3 changed, 1 added, 1 removed
//candidates = getCandidates(store)
//candidates = GetCandidates(store)
//testChange(t, candidates[0].validator(), change[0])
//testChange(t, candidates[1].validator(), change[1])
//testChange(t, candidates[2].validator(), change[2])
@ -164,7 +164,7 @@ import (
//ctx, _, keeper := createTestInput(t, nil, false, 0)
//candidatesFromAddrs(ctx, keeper, addrs, []int64{400, 200, 0, 0, 0})
//validators := keeper.getValidators(ctx, 2)
//validators := keeper.GetValidators(ctx, 2)
//require.Equal(t, 2, len(validators))
//assert.Equal(t, addrs[0], validators[0].Address)
//assert.Equal(t, addrs[1], validators[1].Address)
@ -218,26 +218,26 @@ func TestCandidate(t *testing.T) {
}
// check the empty keeper first
_, found := keeper.getCandidate(ctx, addrVal1)
_, found := keeper.GetCandidate(ctx, addrVal1)
assert.False(t, found)
resAddrs := keeper.getCandidates(ctx, 100)
resAddrs := keeper.GetCandidates(ctx, 100)
assert.Zero(t, len(resAddrs))
// set and retrieve a record
keeper.setCandidate(ctx, candidate1)
resCand, found := keeper.getCandidate(ctx, addrVal1)
resCand, found := keeper.GetCandidate(ctx, addrVal1)
assert.True(t, found)
assert.True(t, candidatesEqual(candidate1, resCand), "%v \n %v", resCand, candidate1)
// modify a records, save, and retrieve
candidate1.Liabilities = sdk.NewRat(99)
keeper.setCandidate(ctx, candidate1)
resCand, found = keeper.getCandidate(ctx, addrVal1)
resCand, found = keeper.GetCandidate(ctx, addrVal1)
assert.True(t, found)
assert.True(t, candidatesEqual(candidate1, resCand))
// also test that the address has been added to address list
resAddrs = keeper.getCandidates(ctx, 100)
resAddrs = keeper.GetCandidates(ctx, 100)
require.Equal(t, 1, len(resAddrs))
assert.Equal(t, addrVal1, resAddrs[0].Address)
@ -314,12 +314,12 @@ func TestParams(t *testing.T) {
expParams := defaultParams()
//check that the empty keeper loads the default
resParams := keeper.getParams(ctx)
resParams := keeper.GetParams(ctx)
assert.Equal(t, expParams, resParams)
//modify a params, save, and retrieve
expParams.MaxValidators = 777
keeper.setParams(ctx, expParams)
resParams = keeper.getParams(ctx)
resParams = keeper.GetParams(ctx)
assert.Equal(t, expParams, resParams)
}

View File

@ -5,7 +5,7 @@ import (
)
// load/save the global staking state
func (k Keeper) getPool(ctx sdk.Context) (gs Pool) {
func (k Keeper) GetPool(ctx sdk.Context) (gs Pool) {
// check if cached before anything
if k.gs != (Pool{}) {
return k.gs
@ -59,7 +59,7 @@ func (k Keeper) unbondedToBondedPool(ctx sdk.Context, candidate Candidate) {
//_______________________________________________________________________
func (k Keeper) addTokensBonded(ctx sdk.Context, amount int64) (issuedShares sdk.Rat) {
p := k.getPool(ctx)
p := k.GetPool(ctx)
issuedShares = p.bondedShareExRate().Inv().Mul(sdk.NewRat(amount)) // (tokens/shares)^-1 * tokens
p.BondedPool += amount
p.BondedShares = p.BondedShares.Add(issuedShares)
@ -68,7 +68,7 @@ func (k Keeper) addTokensBonded(ctx sdk.Context, amount int64) (issuedShares sdk
}
func (k Keeper) removeSharesBonded(ctx sdk.Context, shares sdk.Rat) (removedTokens int64) {
p := k.getPool(ctx)
p := k.GetPool(ctx)
removedTokens = p.bondedShareExRate().Mul(shares).Evaluate() // (tokens/shares) * shares
p.BondedShares = p.BondedShares.Sub(shares)
p.BondedPool -= removedTokens
@ -77,7 +77,7 @@ func (k Keeper) removeSharesBonded(ctx sdk.Context, shares sdk.Rat) (removedToke
}
func (k Keeper) addTokensUnbonded(ctx sdk.Context, amount int64) (issuedShares sdk.Rat) {
p := k.getPool(ctx)
p := k.GetPool(ctx)
issuedShares = p.unbondedShareExRate().Inv().Mul(sdk.NewRat(amount)) // (tokens/shares)^-1 * tokens
p.UnbondedShares = p.UnbondedShares.Add(issuedShares)
p.UnbondedPool += amount
@ -86,7 +86,7 @@ func (k Keeper) addTokensUnbonded(ctx sdk.Context, amount int64) (issuedShares s
}
func (k Keeper) removeSharesUnbonded(ctx sdk.Context, shares sdk.Rat) (removedTokens int64) {
p := k.getPool(ctx)
p := k.GetPool(ctx)
removedTokens = p.unbondedShareExRate().Mul(shares).Evaluate() // (tokens/shares) * shares
p.UnbondedShares = p.UnbondedShares.Sub(shares)
p.UnbondedPool -= removedTokens
@ -99,7 +99,7 @@ func (k Keeper) removeSharesUnbonded(ctx sdk.Context, shares sdk.Rat) (removedTo
// add tokens to a candidate
func (k Keeper) candidateAddTokens(ctx sdk.Context, candidate Candidate, amount int64) (issuedDelegatorShares sdk.Rat) {
p := k.getPool(ctx)
p := k.GetPool(ctx)
exRate := candidate.delegatorShareExRate()
var receivedGlobalShares sdk.Rat
@ -119,7 +119,7 @@ func (k Keeper) candidateAddTokens(ctx sdk.Context, candidate Candidate, amount
// remove shares from a candidate
func (k Keeper) candidateRemoveShares(ctx sdk.Context, candidate Candidate, shares sdk.Rat) (createdCoins int64) {
p := k.getPool(ctx)
p := k.GetPool(ctx)
//exRate := candidate.delegatorShareExRate() //XXX make sure not used
globalPoolSharesToRemove := candidate.delegatorShareExRate().Mul(shares)

View File

@ -11,12 +11,12 @@ func TestPool(t *testing.T) {
expPool := initialPool()
//check that the empty keeper loads the default
resPool := keeper.getPool(ctx)
resPool := keeper.GetPool(ctx)
assert.Equal(t, expPool, resPool)
//modify a params, save, and retrieve
expPool.TotalSupply = 777
keeper.setPool(ctx, expPool)
resPool = keeper.getPool(ctx)
resPool = keeper.GetPool(ctx)
assert.Equal(t, expPool, resPool)
}

View File

@ -91,7 +91,7 @@ func createTestInput(t *testing.T, sender sdk.Address, isCheckTx bool, initCoins
keeper := NewKeeper(ctx, cdc, keyStake, ck)
//params := paramsNoInflation()
params := keeper.getParams(ctx)
params := keeper.GetParams(ctx)
// fill all the addresses with some coins
for _, addr := range addrs {

View File

@ -5,53 +5,57 @@ import (
abci "github.com/tendermint/abci/types"
)
const (
hrsPerYear = 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
// Tick - called at the end of every block
func Tick(ctx sdk.Context, k Keeper) (change []*abci.Validator, err error) {
func (k Keeper) Tick(ctx sdk.Context) (change []*abci.Validator, err error) {
// retrieve params
params := k.getParams(ctx)
p := k.getPool(ctx)
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
processProvisions(ctx, k, p, params)
k.processProvisions(ctx)
}
newVals := k.getValidators(ctx, params.MaxValidators)
newVals := k.GetValidators(ctx)
// XXX determine change from old validators, set to change
_ = newVals
return change, nil
}
var hrsPerYr = sdk.NewRat(8766) // as defined by a julian year of 365.25 days
// process provisions for an hour period
func processProvisions(ctx sdk.Context, k Keeper, p Pool, params Params) {
func (k Keeper) processProvisions(ctx sdk.Context) {
p.Inflation = nextInflation(p, params).Round(1000000000)
pool := k.GetPool(ctx)
pool.Inflation = k.nextInflation(ctx).Round(precision) //TODO make this number a const somewhere?
// Because the validators hold a relative bonded share (`GlobalStakeShare`), when
// 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 := p.Inflation.Mul(sdk.NewRat(p.TotalSupply)).Quo(hrsPerYr).Evaluate()
p.BondedPool += provisions
p.TotalSupply += provisions
// XXX XXX XXX XXX XXX XXX XXX XXX XXX
// XXX Mint them to the hold account
// XXX XXX XXX XXX XXX XXX XXX XXX XXX
provisions := pool.Inflation.Mul(sdk.NewRat(pool.TotalSupply)).Quo(hrsPerYrRat).Evaluate()
pool.BondedPool += provisions
pool.TotalSupply += provisions
// save the params
k.setPool(ctx, p)
k.setPool(ctx, pool)
}
// get the next inflation rate for the hour
func nextInflation(p Pool, params Params) (inflation sdk.Rat) {
func (k Keeper) nextInflation(ctx sdk.Context) (inflation sdk.Rat) {
params := k.GetParams(ctx)
pool := k.GetPool(ctx)
// The target annual inflation rate is recalculated for each previsions cycle. The
// inflation is also subject to a rate change (positive of negative) depending or
// the distance from the desired ratio (67%). The maximum rate change possible is
@ -59,11 +63,11 @@ func nextInflation(p Pool, params Params) (inflation sdk.Rat) {
// 7% and 20%.
// (1 - bondedRatio/GoalBonded) * InflationRateChange
inflationRateChangePerYear := sdk.OneRat.Sub(p.bondedRatio().Quo(params.GoalBonded)).Mul(params.InflationRateChange)
inflationRateChange := inflationRateChangePerYear.Quo(hrsPerYr)
inflationRateChangePerYear := sdk.OneRat.Sub(pool.bondedRatio().Quo(params.GoalBonded)).Mul(params.InflationRateChange)
inflationRateChange := inflationRateChangePerYear.Quo(hrsPerYrRat)
// increase the new annual inflation for this next cycle
inflation = p.Inflation.Add(inflationRateChange)
inflation = pool.Inflation.Add(inflationRateChange)
if inflation.GT(params.InflationMax) {
inflation = params.InflationMax
}

View File

@ -11,7 +11,7 @@ package stake
//ctx, _, keeper := createTestInput(t, nil, false, 0)
//params := defaultParams()
//keeper.setParams(ctx, params)
//gs := keeper.getPool(ctx)
//gs := keeper.GetPool(ctx)
//// Governing Mechanism:
//// bondedRatio = BondedPool / TotalSupply
@ -57,7 +57,7 @@ package stake
//ctx, _, keeper := createTestInput(t, nil, false, 0)
//params := defaultParams()
//keeper.setParams(ctx, params)
//gs := keeper.getPool(ctx)
//gs := keeper.GetPool(ctx)
//// create some candidates some bonded, some unbonded
//candidates := candidatesFromAddrsEmpty(addrs)