cosmos-sdk/x/stake/keeper.go

626 lines
19 KiB
Go
Raw Normal View History

2018-03-20 06:56:07 -07:00
package stake
import (
"bytes"
2018-03-20 06:56:07 -07:00
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/bank"
abci "github.com/tendermint/abci/types"
2018-03-20 06:56:07 -07:00
)
// keeper of the staking store
type Keeper struct {
storeKey sdk.StoreKey
cdc *wire.Codec
2018-04-18 21:49:24 -07:00
coinKeeper bank.Keeper
2018-03-20 06:56:07 -07:00
// codespace
codespace sdk.CodespaceType
2018-03-20 06:56:07 -07:00
}
2018-04-18 21:49:24 -07:00
func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper {
2018-03-20 06:56:07 -07:00
keeper := Keeper{
storeKey: key,
cdc: cdc,
coinKeeper: ck,
codespace: codespace,
2018-03-20 06:56:07 -07:00
}
return keeper
}
2018-03-22 09:00:45 -07:00
//_________________________________________________________________________
2018-05-09 21:01:58 -07:00
// get a single validator
func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.Address) (validator Validator, found bool) {
2018-03-20 14:21:18 -07:00
store := ctx.KVStore(k.storeKey)
2018-05-09 21:01:58 -07:00
b := store.Get(GetValidatorKey(addr))
2018-03-20 06:56:07 -07:00
if b == nil {
2018-05-09 21:01:58 -07:00
return validator, false
2018-03-20 06:56:07 -07:00
}
2018-05-09 21:01:58 -07:00
k.cdc.MustUnmarshalBinary(b, &validator)
return validator, true
2018-03-20 06:56:07 -07:00
}
// 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)
iterator := store.SubspaceIterator(ValidatorsKey)
i := 0
for ; ; i++ {
if !iterator.Valid() {
iterator.Close()
break
}
bz := iterator.Value()
var validator Validator
k.cdc.MustUnmarshalBinary(bz, &validator)
validators = append(validators, validator)
iterator.Next()
}
return validators[:i] // trim
}
2018-05-09 21:01:58 -07:00
// Get the set of all validators, retrieve a maxRetrieve number of records
func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve int16) (validators Validators) {
2018-03-22 09:00:45 -07:00
store := ctx.KVStore(k.storeKey)
2018-05-09 21:01:58 -07:00
iterator := store.SubspaceIterator(ValidatorsKey)
2018-03-20 06:56:07 -07:00
2018-05-09 21:01:58 -07:00
validators = make([]Validator, maxRetrieve)
2018-03-22 09:00:45 -07:00
i := 0
for ; ; i++ {
2018-04-24 06:46:39 -07:00
if !iterator.Valid() || i > int(maxRetrieve-1) {
2018-03-22 09:00:45 -07:00
iterator.Close()
break
}
bz := iterator.Value()
2018-05-09 21:01:58 -07:00
var validator Validator
k.cdc.MustUnmarshalBinary(bz, &validator)
validators[i] = validator
2018-03-22 09:00:45 -07:00
iterator.Next()
}
2018-05-09 21:01:58 -07:00
return validators[:i] // trim
2018-03-22 09:00:45 -07:00
}
func (k Keeper) setValidator(ctx sdk.Context, validator Validator) Validator {
2018-03-20 14:21:18 -07:00
store := ctx.KVStore(k.storeKey)
pool := k.getPool(store)
2018-05-09 21:01:58 -07:00
address := validator.Address
2018-03-20 06:56:07 -07:00
// update the main list ordered by address before exiting
defer func() {
bz := k.cdc.MustMarshalBinary(validator)
store.Set(GetValidatorKey(address), bz)
}()
2018-05-09 21:01:58 -07:00
// retreive the old validator record
oldValidator, oldFound := k.GetValidator(ctx, address)
2018-03-22 14:47:57 -07:00
2018-05-07 14:57:35 -07:00
powerIncreasing := false
2018-03-22 14:47:57 -07:00
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.PShares.Equal(validator.PShares) {
return validator
} else if oldValidator.PShares.Bonded().LT(validator.PShares.Bonded()) {
2018-05-07 14:57:35 -07:00
powerIncreasing = true
2018-05-04 18:29:12 -07:00
}
2018-05-04 16:15:24 -07:00
// delete the old record in the power ordered list
store.Delete(GetValidatorsBondedByPowerKey(oldValidator, pool))
2018-03-22 14:47:57 -07:00
}
2018-04-09 04:12:08 -07:00
2018-05-07 14:57:35 -07:00
// if already a validator, copy the old block height and counter, else set them
2018-05-10 17:08:18 -07:00
if oldFound && oldValidator.Status == sdk.Bonded {
validator.BondHeight = oldValidator.BondHeight
validator.BondIntraTxCounter = oldValidator.BondIntraTxCounter
2018-05-07 14:57:35 -07:00
} else {
2018-05-10 17:08:18 -07:00
validator.BondHeight = ctx.BlockHeight()
2018-05-07 14:57:35 -07:00
counter := k.getIntraTxCounter(ctx)
2018-05-10 17:08:18 -07:00
validator.BondIntraTxCounter = counter
2018-05-07 14:57:35 -07:00
k.setIntraTxCounter(ctx, counter+1)
}
2018-05-04 18:29:12 -07:00
// update the list ordered by voting power
2018-05-12 12:45:40 -07:00
bz := k.cdc.MustMarshalBinary(validator)
store.Set(GetValidatorsBondedByPowerKey(validator, pool), bz)
2018-03-22 14:47:57 -07:00
// efficiency case:
2018-05-07 14:57:35 -07:00
// add to the validators and return to update list if is already a validator and power is increasing
if powerIncreasing && oldFound && oldValidator.Status == sdk.Bonded {
2018-04-09 03:17:45 -07:00
// update the store for bonded validators
2018-05-12 12:45:40 -07:00
store.Set(GetValidatorsBondedKey(validator.PubKey), bz)
// and the Tendermint updates
bz := k.cdc.MustMarshalBinary(validator.abciValidator(k.cdc))
store.Set(GetTendermintUpdatesKey(address), bz)
return validator
2018-05-04 16:15:24 -07:00
}
2018-05-03 23:00:30 -07:00
2018-05-10 17:08:18 -07:00
// update the validator set for this validator
nowBonded, retrieve := k.updateBondedValidators(ctx, store, pool, validator.Address)
if nowBonded {
validator = retrieve
}
return validator
2018-03-20 06:56:07 -07:00
}
2018-05-09 21:01:58 -07:00
func (k Keeper) removeValidator(ctx sdk.Context, address sdk.Address) {
2018-03-20 06:56:07 -07:00
2018-05-09 21:01:58 -07:00
// first retreive the old validator record
validator, found := k.GetValidator(ctx, address)
2018-03-22 14:47:57 -07:00
if !found {
return
}
2018-05-09 21:01:58 -07:00
// delete the old validator record
2018-03-22 14:47:57 -07:00
store := ctx.KVStore(k.storeKey)
pool := k.getPool(store)
2018-05-09 21:01:58 -07:00
store.Delete(GetValidatorKey(address))
store.Delete(GetValidatorsBondedByPowerKey(validator, pool))
2018-03-22 09:00:45 -07:00
2018-05-17 12:48:47 -07:00
// delete from the current and power weighted validator groups if the validator
// is bonded - and add validator with zero power to the validator updates
2018-05-06 15:18:52 -07:00
if store.Get(GetValidatorsBondedKey(validator.PubKey)) == nil {
2018-03-22 14:47:57 -07:00
return
}
2018-05-09 21:01:58 -07:00
bz := k.cdc.MustMarshalBinary(validator.abciValidatorZero(k.cdc))
2018-05-10 18:38:57 -07:00
store.Set(GetTendermintUpdatesKey(address), bz)
2018-05-06 15:18:52 -07:00
store.Delete(GetValidatorsBondedKey(validator.PubKey))
2018-03-20 06:56:07 -07:00
}
2018-03-22 14:47:57 -07:00
//___________________________________________________________________________
2018-05-09 20:47:58 -07:00
// get the group of the bonded validators
func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []Validator) {
2018-03-20 14:21:18 -07:00
store := ctx.KVStore(k.storeKey)
2018-03-20 06:56:07 -07:00
2018-05-04 18:29:12 -07:00
// add the actual validator power sorted store
maxValidators := k.GetParams(ctx).MaxValidators
validators = make([]Validator, maxValidators)
2018-05-09 20:28:00 -07:00
iterator := store.SubspaceIterator(ValidatorsBondedKey)
2018-05-04 18:29:12 -07:00
i := 0
for ; iterator.Valid(); iterator.Next() {
2018-05-17 12:48:47 -07:00
// sanity check
if i > int(maxValidators-1) {
panic("maxValidators is less than the number of records in ValidatorsBonded Store, store should have been updated")
}
2018-05-04 18:29:12 -07:00
bz := iterator.Value()
var validator Validator
k.cdc.MustUnmarshalBinary(bz, &validator)
validators[i] = validator
i++
}
iterator.Close()
return validators[:i] // trim
}
2018-05-09 20:47:58 -07:00
// get the group of bonded validators sorted by power-rank
func (k Keeper) GetValidatorsBondedByPower(ctx sdk.Context) []Validator {
2018-05-09 21:01:58 -07:00
store := ctx.KVStore(k.storeKey)
2018-05-09 20:47:58 -07:00
maxValidators := k.GetParams(ctx).MaxValidators
2018-05-09 21:01:58 -07:00
validators := make([]Validator, maxValidators)
iterator := store.ReverseSubspaceIterator(ValidatorsByPowerKey) // largest to smallest
2018-05-09 20:47:58 -07:00
i := 0
2018-05-16 08:59:16 -07:00
for {
2018-05-09 20:47:58 -07:00
if !iterator.Valid() || i > int(maxValidators-1) {
iterator.Close()
break
}
bz := iterator.Value()
var validator Validator
k.cdc.MustUnmarshalBinary(bz, &validator)
2018-05-16 08:59:16 -07:00
if validator.Status == sdk.Bonded {
validators[i] = validator
i++
}
2018-05-09 20:47:58 -07:00
iterator.Next()
2018-05-04 18:29:12 -07:00
}
2018-05-12 12:45:40 -07:00
return validators[:i] // trim
2018-05-04 18:29:12 -07:00
}
// XXX TODO build in consideration for revoked
//
2018-05-07 14:57:35 -07:00
// Update the validator group and kick out any old validators. In addition this
2018-05-10 17:08:18 -07:00
// function adds (or doesn't add) a validator which has updated its bonded
// tokens to the validator group. -> this validator is specified through the
// updatedValidatorAddr term.
2018-05-04 18:29:12 -07:00
//
// The correct subset is retrieved by iterating through an index of the
2018-05-09 21:01:58 -07:00
// validators sorted by power, stored using the ValidatorsByPowerKey. Simultaniously
2018-05-09 18:39:14 -07:00
// the current validator records are updated in store with the
2018-05-09 21:01:58 -07:00
// ValidatorsBondedKey. This store is used to determine if a validator is a
2018-05-04 18:29:12 -07:00
// validator without needing to iterate over the subspace as we do in
2018-05-07 14:57:35 -07:00
// GetValidators.
//
// Optionally also return the validator from a retrieve address if the validator has been bonded
func (k Keeper) updateBondedValidators(ctx sdk.Context, store sdk.KVStore, pool Pool,
OptionalRetrieve sdk.Address) (retrieveBonded bool, retrieve Validator) {
2018-05-04 18:29:12 -07:00
2018-05-09 18:39:14 -07:00
// clear the current validators store, add to the ToKickOut temp store
2018-05-10 16:02:35 -07:00
toKickOut := make(map[string][]byte) // map[key]value
2018-05-09 20:28:00 -07:00
iterator := store.SubspaceIterator(ValidatorsBondedKey)
2018-04-02 11:37:35 -07:00
for ; iterator.Valid(); iterator.Next() {
bz := iterator.Value()
var validator Validator
k.cdc.MustUnmarshalBinary(bz, &validator)
2018-05-04 18:29:12 -07:00
addr := validator.Address
// iterator.Value is the validator object
2018-05-10 16:02:35 -07:00
toKickOut[string(addr)] = iterator.Value()
2018-04-02 11:37:35 -07:00
store.Delete(iterator.Key())
}
iterator.Close()
2018-03-20 06:56:07 -07:00
2018-03-22 14:47:57 -07:00
// add the actual validator power sorted store
maxValidators := k.GetParams(ctx).MaxValidators
2018-05-09 20:28:00 -07:00
iterator = store.ReverseSubspaceIterator(ValidatorsByPowerKey) // largest to smallest
i := 0
for ; ; i++ {
if !iterator.Valid() || i > int(maxValidators-1) {
2018-03-20 06:56:07 -07:00
iterator.Close()
break
}
2018-03-22 14:47:57 -07:00
bz := iterator.Value()
var validator Validator
k.cdc.MustUnmarshalBinary(bz, &validator)
2018-03-22 14:47:57 -07:00
_, found := toKickOut[string(validator.Address)]
if found {
// remove from ToKickOut group
2018-05-17 12:48:47 -07:00
delete(toKickOut, string(validator.Address))
} else {
// if it wasn't in the toKickOut group it means
// this wasn't a previously a validator, therefor
// update the validator/to reflect this
validator.Status = sdk.Bonded
validator, pool = validator.UpdateSharesLocation(pool)
validator = k.bondValidator(ctx, store, validator, pool)
if bytes.Equal(validator.Address, OptionalRetrieve) {
retrieveBonded = true
retrieve = validator
}
}
2018-04-02 11:37:35 -07:00
2018-05-09 18:39:14 -07:00
// also add to the current validators group
2018-05-06 15:18:52 -07:00
store.Set(GetValidatorsBondedKey(validator.PubKey), bz)
2018-03-22 14:47:57 -07:00
2018-03-20 06:56:07 -07:00
iterator.Next()
}
2018-03-22 14:47:57 -07:00
// perform the actual kicks
2018-05-16 08:59:16 -07:00
for _, value := range toKickOut {
var validator Validator
2018-05-09 20:28:00 -07:00
k.cdc.MustUnmarshalBinary(value, &validator)
2018-05-16 08:59:16 -07:00
k.unbondValidator(ctx, store, validator)
2018-04-02 11:37:35 -07:00
}
// save the pool as well before exiting
k.setPool(ctx, pool)
return
2018-03-22 14:47:57 -07:00
}
// perform all the store operations for when a validator status becomes unbonded
2018-05-16 08:59:16 -07:00
func (k Keeper) unbondValidator(ctx sdk.Context, store sdk.KVStore, validator Validator) {
pool := k.GetPool(ctx)
// set the status
validator.Status = sdk.Unbonded
validator, pool = validator.UpdateSharesLocation(pool)
k.setPool(ctx, pool)
// save the now unbonded validator record
bz := k.cdc.MustMarshalBinary(validator)
store.Set(GetValidatorKey(validator.Address), bz)
// add to accumulated changes for tendermint
bz = k.cdc.MustMarshalBinary(validator.abciValidatorZero(k.cdc))
store.Set(GetTendermintUpdatesKey(validator.Address), bz)
// also remove from the Bonded Validators Store
store.Delete(GetValidatorsBondedKey(validator.PubKey))
}
// perform all the store operations for when a validator status becomes bonded
func (k Keeper) bondValidator(ctx sdk.Context, store sdk.KVStore, validator Validator, pool Pool) Validator {
2018-05-17 12:48:47 -07:00
// first delete the old record in the pool
store.Delete(GetValidatorsBondedByPowerKey(validator, pool))
// set the status
validator.Status = sdk.Bonded
validator, pool = validator.UpdateSharesLocation(pool)
k.setPool(ctx, pool)
// save the now bonded validator record to the three referened stores
bzVal := k.cdc.MustMarshalBinary(validator)
store.Set(GetValidatorKey(validator.Address), bzVal)
store.Set(GetValidatorsBondedByPowerKey(validator, pool), bzVal)
store.Set(GetValidatorsBondedKey(validator.PubKey), bzVal)
// add to accumulated changes for tendermint
bzABCI := k.cdc.MustMarshalBinary(validator.abciValidator(k.cdc))
store.Set(GetTendermintUpdatesKey(validator.Address), bzABCI)
return validator
}
2018-03-20 06:56:07 -07:00
//_________________________________________________________________________
2018-05-09 20:47:58 -07:00
// Accumulated updates to the active/bonded validator set for tendermint
2018-03-20 06:56:07 -07:00
2018-03-22 14:47:57 -07:00
// get the most recently updated validators
2018-05-10 18:38:57 -07:00
func (k Keeper) getTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) {
2018-03-20 14:21:18 -07:00
store := ctx.KVStore(k.storeKey)
2018-03-20 06:56:07 -07:00
2018-05-10 18:38:57 -07:00
iterator := store.SubspaceIterator(TendermintUpdatesKey) //smallest to largest
2018-03-20 06:56:07 -07:00
for ; iterator.Valid(); iterator.Next() {
valBytes := iterator.Value()
var val abci.Validator
k.cdc.MustUnmarshalBinary(valBytes, &val)
2018-03-20 06:56:07 -07:00
updates = append(updates, val)
}
iterator.Close()
return
}
2018-05-09 18:39:14 -07:00
// remove all validator update entries after applied to Tendermint
2018-05-10 18:38:57 -07:00
func (k Keeper) clearTendermintUpdates(ctx sdk.Context) {
2018-03-20 14:21:18 -07:00
store := ctx.KVStore(k.storeKey)
2018-03-22 14:47:57 -07:00
// delete subspace
2018-05-10 18:38:57 -07:00
iterator := store.SubspaceIterator(TendermintUpdatesKey)
2018-03-20 06:56:07 -07:00
for ; iterator.Valid(); iterator.Next() {
2018-03-22 14:47:57 -07:00
store.Delete(iterator.Key())
2018-03-20 06:56:07 -07:00
}
iterator.Close()
}
//_____________________________________________________________________
2018-04-23 09:17:21 -07:00
// load a delegator bond
2018-05-09 18:39:14 -07:00
func (k Keeper) GetDelegation(ctx sdk.Context,
2018-05-09 21:01:58 -07:00
delegatorAddr, validatorAddr sdk.Address) (bond Delegation, found bool) {
2018-03-20 06:56:07 -07:00
2018-03-20 14:21:18 -07:00
store := ctx.KVStore(k.storeKey)
2018-05-09 21:01:58 -07:00
delegatorBytes := store.Get(GetDelegationKey(delegatorAddr, validatorAddr, k.cdc))
2018-03-20 06:56:07 -07:00
if delegatorBytes == nil {
2018-03-20 14:21:18 -07:00
return bond, false
2018-03-20 06:56:07 -07:00
}
k.cdc.MustUnmarshalBinary(delegatorBytes, &bond)
2018-03-20 14:21:18 -07:00
return bond, true
2018-03-20 06:56:07 -07:00
}
// load all delegations used during genesis dump
func (k Keeper) getAllDelegations(ctx sdk.Context) (delegations []Delegation) {
store := ctx.KVStore(k.storeKey)
2018-05-09 20:28:00 -07:00
iterator := store.SubspaceIterator(DelegationKey)
i := 0
for ; ; i++ {
if !iterator.Valid() {
iterator.Close()
break
}
bondBytes := iterator.Value()
var delegation Delegation
k.cdc.MustUnmarshalBinary(bondBytes, &delegation)
delegations = append(delegations, delegation)
iterator.Next()
}
return delegations[:i] // trim
}
2018-03-22 09:00:45 -07:00
// load all bonds of a delegator
2018-05-09 18:39:14 -07:00
func (k Keeper) GetDelegations(ctx sdk.Context, delegator sdk.Address, maxRetrieve int16) (bonds []Delegation) {
2018-03-22 09:00:45 -07:00
store := ctx.KVStore(k.storeKey)
2018-05-09 18:39:14 -07:00
delegatorPrefixKey := GetDelegationsKey(delegator, k.cdc)
iterator := store.SubspaceIterator(delegatorPrefixKey) //smallest to largest
2018-03-22 09:00:45 -07:00
2018-05-09 18:39:14 -07:00
bonds = make([]Delegation, maxRetrieve)
2018-03-22 09:00:45 -07:00
i := 0
for ; ; i++ {
if !iterator.Valid() || i > int(maxRetrieve-1) {
iterator.Close()
break
}
bondBytes := iterator.Value()
2018-05-09 18:39:14 -07:00
var bond Delegation
k.cdc.MustUnmarshalBinary(bondBytes, &bond)
2018-03-22 09:00:45 -07:00
bonds[i] = bond
iterator.Next()
}
return bonds[:i] // trim
2018-03-20 06:56:07 -07:00
}
2018-05-09 18:39:14 -07:00
func (k Keeper) setDelegation(ctx sdk.Context, bond Delegation) {
2018-03-22 14:47:57 -07:00
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(bond)
2018-05-09 21:01:58 -07:00
store.Set(GetDelegationKey(bond.DelegatorAddr, bond.ValidatorAddr, k.cdc), b)
2018-03-22 14:47:57 -07:00
}
2018-05-09 18:39:14 -07:00
func (k Keeper) removeDelegation(ctx sdk.Context, bond Delegation) {
2018-03-22 14:47:57 -07:00
store := ctx.KVStore(k.storeKey)
2018-05-09 21:01:58 -07:00
store.Delete(GetDelegationKey(bond.DelegatorAddr, bond.ValidatorAddr, k.cdc))
2018-03-22 14:47:57 -07:00
}
2018-03-20 06:56:07 -07:00
//_______________________________________________________________________
// load/save the global staking params
func (k Keeper) GetParams(ctx sdk.Context) Params {
2018-03-20 14:21:18 -07:00
store := ctx.KVStore(k.storeKey)
return k.getParams(store)
}
func (k Keeper) getParams(store sdk.KVStore) (params Params) {
2018-03-20 06:56:07 -07:00
b := store.Get(ParamKey)
if b == nil {
2018-04-03 11:50:31 -07:00
panic("Stored params should not have been nil")
2018-03-20 06:56:07 -07:00
}
k.cdc.MustUnmarshalBinary(b, &params)
2018-03-20 06:56:07 -07:00
return
}
func (k Keeper) setNewParams(ctx sdk.Context, params Params) {
2018-03-20 14:21:18 -07:00
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(params)
2018-03-20 06:56:07 -07:00
store.Set(ParamKey, b)
}
func (k Keeper) setParams(ctx sdk.Context, params Params) {
store := ctx.KVStore(k.storeKey)
exParams := k.getParams(store)
2018-05-07 14:57:35 -07:00
2018-05-06 15:18:52 -07:00
// if max validator count changes, must recalculate validator set
if exParams.MaxValidators != params.MaxValidators {
pool := k.GetPool(ctx)
k.updateBondedValidators(ctx, store, pool, nil)
2018-05-06 15:18:52 -07:00
}
b := k.cdc.MustMarshalBinary(params)
store.Set(ParamKey, b)
2018-03-20 06:56:07 -07:00
}
2018-03-28 13:37:42 -07:00
//_______________________________________________________________________
// load/save the pool
2018-04-30 14:21:14 -07:00
func (k Keeper) GetPool(ctx sdk.Context) (pool Pool) {
store := ctx.KVStore(k.storeKey)
return k.getPool(store)
}
func (k Keeper) getPool(store sdk.KVStore) (pool Pool) {
2018-03-28 13:37:42 -07:00
b := store.Get(PoolKey)
if b == nil {
2018-04-03 11:50:31 -07:00
panic("Stored pool should not have been nil")
2018-03-28 13:37:42 -07:00
}
k.cdc.MustUnmarshalBinary(b, &pool)
2018-03-28 13:37:42 -07:00
return
}
func (k Keeper) setPool(ctx sdk.Context, p Pool) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(p)
2018-03-28 13:37:42 -07:00
store.Set(PoolKey, b)
}
2018-04-25 07:12:59 -07:00
//__________________________________________________________________________
// get the current in-block validator operation counter
func (k Keeper) getIntraTxCounter(ctx sdk.Context) int16 {
store := ctx.KVStore(k.storeKey)
b := store.Get(IntraTxCounterKey)
if b == nil {
return 0
}
var counter int16
k.cdc.MustUnmarshalBinary(b, &counter)
return counter
}
// set the current in-block validator operation counter
func (k Keeper) setIntraTxCounter(ctx sdk.Context, counter int16) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(counter)
store.Set(IntraTxCounterKey, bz)
}
//__________________________________________________________________________
2018-05-09 18:39:14 -07:00
// Implements ValidatorSet
2018-05-09 18:39:14 -07:00
var _ sdk.ValidatorSet = Keeper{}
2018-05-09 18:39:14 -07:00
// iterate through the active validator set and perform the provided function
func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) {
store := ctx.KVStore(k.storeKey)
iterator := store.SubspaceIterator(ValidatorsKey)
i := int64(0)
for ; iterator.Valid(); iterator.Next() {
bz := iterator.Value()
var validator Validator
k.cdc.MustUnmarshalBinary(bz, &validator)
stop := fn(i, validator) // XXX is this safe will the validator unexposed fields be able to get written to?
if stop {
break
}
i++
}
iterator.Close()
}
// 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)) {
2018-05-09 21:01:58 -07:00
store := ctx.KVStore(k.storeKey)
2018-05-09 20:28:00 -07:00
iterator := store.SubspaceIterator(ValidatorsBondedKey)
2018-05-10 16:02:35 -07:00
i := int64(0)
2018-05-09 18:39:14 -07:00
for ; iterator.Valid(); iterator.Next() {
bz := iterator.Value()
var validator Validator
k.cdc.MustUnmarshalBinary(bz, &validator)
stop := fn(i, validator) // XXX is this safe will the validator unexposed fields be able to get written to?
if stop {
break
}
2018-05-09 18:39:14 -07:00
i++
}
iterator.Close()
2018-04-25 07:12:59 -07:00
}
2018-05-09 18:39:14 -07:00
// get the sdk.validator for a particular address
2018-05-06 11:39:50 -07:00
func (k Keeper) Validator(ctx sdk.Context, addr sdk.Address) sdk.Validator {
2018-05-09 21:01:58 -07:00
val, found := k.GetValidator(ctx, addr)
if !found {
2018-04-25 07:12:59 -07:00
return nil
}
2018-05-09 21:01:58 -07:00
return val
2018-04-25 07:12:59 -07:00
}
2018-05-09 18:39:14 -07:00
// total power from the bond
2018-04-17 14:38:12 -07:00
func (k Keeper) TotalPower(ctx sdk.Context) sdk.Rat {
2018-05-02 11:50:50 -07:00
pool := k.GetPool(ctx)
return pool.BondedShares
2018-04-25 07:12:59 -07:00
}
2018-05-06 11:39:50 -07:00
2018-05-09 18:39:14 -07:00
//__________________________________________________________________________
// Implements DelegationSet
var _ sdk.ValidatorSet = Keeper{}
// get the delegation for a particular set of delegator and validator addresses
func (k Keeper) Delegation(ctx sdk.Context, addrDel sdk.Address, addrVal sdk.Address) sdk.Delegation {
bond, ok := k.GetDelegation(ctx, addrDel, addrVal)
2018-05-06 11:39:50 -07:00
if !ok {
return nil
}
return bond
}
2018-05-09 18:39:14 -07:00
// iterate through the active validator set and perform the provided function
func (k Keeper) IterateDelegators(ctx sdk.Context, delAddr sdk.Address, fn func(index int64, delegation sdk.Delegation) (stop bool)) {
2018-05-10 16:02:35 -07:00
store := ctx.KVStore(k.storeKey)
2018-05-09 18:39:14 -07:00
key := GetDelegationsKey(delAddr, k.cdc)
2018-05-10 16:02:35 -07:00
iterator := store.SubspaceIterator(key)
i := int64(0)
2018-05-09 18:39:14 -07:00
for ; iterator.Valid(); iterator.Next() {
bz := iterator.Value()
var delegation Delegation
k.cdc.MustUnmarshalBinary(bz, &delegation)
stop := fn(i, delegation) // XXX is this safe will the fields be able to get written to?
if stop {
break
}
2018-05-09 18:39:14 -07:00
i++
}
iterator.Close()
2018-05-06 11:39:50 -07:00
}