major keeper revisions

This commit is contained in:
rigelrozanski 2018-03-22 22:47:57 +01:00
parent 5ba297089a
commit 27e0bbca4e
3 changed files with 126 additions and 91 deletions

View File

@ -45,7 +45,7 @@ func GetCmdQueryCandidates(cdc *wire.Codec, storeName string) *cobra.Command {
Short: "Query for the set of validator-candidates pubkeys",
RunE: func(cmd *cobra.Command, args []string) error {
key := PrefixedKey(stake.MsgType, stake.CandidatesAddrKey)
key := PrefixedKey(stake.MsgType, stake.CandidatesKey)
res, err := builder.Query(key, storeName)
if err != nil {

View File

@ -12,7 +12,7 @@ type Keeper struct {
cdc *wire.Codec
coinKeeper bank.CoinKeeper
//just caches
// caches
gs Pool
params Params
}
@ -42,30 +42,10 @@ func (k Keeper) GetCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candi
return candidate, true
}
func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) {
store := ctx.KVStore(k.storeKey)
k.removeValidator(ctx, candidate.Address)
validator := Validator{candidate.Address, candidate.VotingPower}
k.updateValidator(ctx, validator)
b, err := k.cdc.MarshalBinary(candidate)
if err != nil {
panic(err)
}
store.Set(GetCandidateKey(candidate.Address), b)
}
func (k Keeper) removeCandidate(ctx sdk.Context, candidateAddr sdk.Address) {
store := ctx.KVStore(k.storeKey)
k.removeValidator(ctx, candidateAddr)
store.Delete(GetCandidateKey(candidateAddr))
}
// 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))
iterator := store.Iterator(subspace(CandidatesKey))
candidates = make([]Candidate, maxRetrieve)
i := 0
@ -86,53 +66,82 @@ func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Ca
return candidates[:i] // trim
}
//___________________________________________________________________________
// updateValidator - update a validator and create accumulate any changes
// in the changed validator substore
func (k Keeper) updateValidator(ctx sdk.Context, validator Validator) {
func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) {
store := ctx.KVStore(k.storeKey)
address := candidate.Address
b, err := k.cdc.MarshalBinary(validator)
// retreive the old candidate record
oldCandidate, oldFound := k.GetCandidate(ctx, address)
// marshal the candidate record and add to the state
bz, err := k.cdc.MarshalBinary(candidate)
if err != nil {
panic(err)
}
store.Set(GetCandidateKey(candidate.Address), bz)
// add to the validators to update list if necessary
store.Set(GetValidatorUpdatesKey(validator.Address), b)
// mashal the new validator record
validator := Validator{address, candidate.VotingPower}
bz, err = k.cdc.MarshalBinary(validator)
if err != nil {
panic(err)
}
// update the list ordered by voting power
store.Set(GetValidatorKey(validator.Address, validator.VotingPower, k.cdc), b)
if oldFound {
store.Delete(GetValidatorKey(address, oldCandidate.VotingPower, k.cdc))
}
store.Set(GetValidatorKey(address, validator.VotingPower, k.cdc), bz)
// add to the validators to update list if is already a validator
if store.Get(GetRecentValidatorKey(address)) == nil {
return
}
store.Set(GetAccUpdateValidatorKey(validator.Address), bz)
}
func (k Keeper) removeValidator(ctx sdk.Context, address sdk.Address) {
func (k Keeper) removeCandidate(ctx sdk.Context, address sdk.Address) {
// first retreive the old candidate record
oldCandidate, found := k.GetCandidate(ctx, address)
if !found {
return
}
// delete the old candidate record
store := ctx.KVStore(k.storeKey)
store.Delete(GetCandidateKey(address))
// XXX ensure that this record is a validator even?
//add validator with zero power to the validator updates
b, err := k.cdc.MarshalBinary(Validator{address, sdk.ZeroRat})
// delete from recent and power weighted validator groups if the validator
// exists and add validator with zero power to the validator updates
if store.Get(GetRecentValidatorKey(address)) == nil {
return
}
bz, err := k.cdc.MarshalBinary(Validator{address, sdk.ZeroRat})
if err != nil {
panic(err)
}
store.Set(GetValidatorUpdatesKey(address), b)
// now actually delete from the validator set
candidate, found := k.GetCandidate(ctx, address)
if found {
store.Delete(GetValidatorKey(address, candidate.VotingPower, k.cdc))
}
store.Set(GetAccUpdateValidatorKey(address), bz)
store.Delete(GetRecentValidatorKey(address))
store.Delete(GetValidatorKey(address, oldCandidate.VotingPower, k.cdc))
}
//___________________________________________________________________________
// 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
// this function also updaates the most recent validators saved in store
func (k Keeper) GetValidators(ctx sdk.Context) (validators []Validator) {
store := ctx.KVStore(k.storeKey)
// clear the recent validators store
k.deleteSubSpace(store, RecentValidatorsKey)
// add the actual validator power sorted store
maxVal := k.GetParams(ctx).MaxValidators
iterator := store.Iterator(subspace(ValidatorKeyPrefix)) //smallest to largest
iterator := store.Iterator(subspace(ValidatorsKey)) //smallest to largest
validators = make([]Validator, maxVal)
i := 0
for ; ; i++ {
@ -140,26 +149,40 @@ func (k Keeper) GetValidators(ctx sdk.Context) (validators []Validator) {
iterator.Close()
break
}
valBytes := iterator.Value()
bz := iterator.Value()
var val Validator
err := k.cdc.UnmarshalBinary(valBytes, &val)
err := k.cdc.UnmarshalBinary(bz, &val)
if err != nil {
panic(err)
}
validators[i] = val
// also add to the recent validators group
store.Set(GetRecentValidatorKey(val.Address), bz)
iterator.Next()
}
return validators[:i] // trim
}
//_________________________________________________________________________
// Is the address provided a part of the most recently saved validator group?
func (k Keeper) IsRecentValidator(ctx sdk.Context, address sdk.Address) bool {
store := ctx.KVStore(k.storeKey)
if store.Get(GetRecentValidatorKey(address)) == nil {
return false
}
return true
}
// get the most updated validators
func (k Keeper) getValidatorUpdates(ctx sdk.Context) (updates []Validator) {
//_________________________________________________________________________
// Accumulated updates to the validator set
// get the most recently updated validators
func (k Keeper) getAccUpdateValidators(ctx sdk.Context) (updates []Validator) {
store := ctx.KVStore(k.storeKey)
iterator := store.Iterator(subspace(ValidatorUpdatesKeyPrefix)) //smallest to largest
iterator := store.Iterator(subspace(AccUpdateValidatorsKey)) //smallest to largest
for ; iterator.Valid(); iterator.Next() {
valBytes := iterator.Value()
var val Validator
@ -169,17 +192,21 @@ func (k Keeper) getValidatorUpdates(ctx sdk.Context) (updates []Validator) {
}
updates = append(updates, val)
}
iterator.Close()
return
}
// remove all validator update entries
func (k Keeper) clearValidatorUpdates(ctx sdk.Context, maxVal int) {
func (k Keeper) clearAccUpdateValidators(ctx sdk.Context) {
store := ctx.KVStore(k.storeKey)
iterator := store.Iterator(subspace(ValidatorUpdatesKeyPrefix))
k.deleteSubSpace(store, AccUpdateValidatorsKey)
}
// TODO move to common functionality somewhere
func (k Keeper) deleteSubSpace(store sdk.KVStore, key []byte) {
iterator := store.Iterator(subspace(key))
for ; iterator.Valid(); iterator.Next() {
store.Delete(iterator.Key()) // XXX write test for this, may need to be in a second loop
store.Delete(iterator.Key())
}
iterator.Close()
}
@ -202,20 +229,6 @@ func (k Keeper) getDelegatorBond(ctx sdk.Context,
return bond, true
}
func (k Keeper) setDelegatorBond(ctx sdk.Context, bond DelegatorBond) {
store := ctx.KVStore(k.storeKey)
b, err := k.cdc.MarshalBinary(bond)
if err != nil {
panic(err)
}
store.Set(GetDelegatorBondKey(bond.DelegatorAddr, bond.CandidateAddr, k.cdc), b)
}
func (k Keeper) removeDelegatorBond(ctx sdk.Context, bond DelegatorBond) {
store := ctx.KVStore(k.storeKey)
store.Delete(GetDelegatorBondKey(bond.DelegatorAddr, bond.CandidateAddr, k.cdc))
}
// load all bonds of a delegator
func (k Keeper) getDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRetrieve int16) (bonds []DelegatorBond) {
store := ctx.KVStore(k.storeKey)
@ -241,6 +254,20 @@ func (k Keeper) getDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRet
return bonds[:i] // trim
}
func (k Keeper) setDelegatorBond(ctx sdk.Context, bond DelegatorBond) {
store := ctx.KVStore(k.storeKey)
b, err := k.cdc.MarshalBinary(bond)
if err != nil {
panic(err)
}
store.Set(GetDelegatorBondKey(bond.DelegatorAddr, bond.CandidateAddr, k.cdc), b)
}
func (k Keeper) removeDelegatorBond(ctx sdk.Context, bond DelegatorBond) {
store := ctx.KVStore(k.storeKey)
store.Delete(GetDelegatorBondKey(bond.DelegatorAddr, bond.CandidateAddr, k.cdc))
}
//_______________________________________________________________________
// load/save the global staking params

View File

@ -5,43 +5,51 @@ import (
"github.com/cosmos/cosmos-sdk/wire"
)
// TODO remove some of these prefixes once have working multistore
//nolint
var (
// Keys for store prefixes
CandidatesAddrKey = []byte{0x01} // key for all candidates' addresses
ParamKey = []byte{0x02} // key for global parameters relating to staking
PoolKey = []byte{0x03} // key for global parameters relating to staking
ParamKey = []byte{0x00} // key for global parameters relating to staking
PoolKey = []byte{0x01} // key for global parameters relating to staking
CandidatesKey = []byte{0x02} // prefix for each key to a candidate
ValidatorsKey = []byte{0x03} // prefix for each key to a validator
AccUpdateValidatorsKey = []byte{0x04} // prefix for each key to a validator which is being updated
RecentValidatorsKey = []byte{0x04} // prefix for each key to the last updated validator group
// Key prefixes
CandidateKeyPrefix = []byte{0x04} // prefix for each key to a candidate
ValidatorKeyPrefix = []byte{0x05} // prefix for each key to a candidate
ValidatorUpdatesKeyPrefix = []byte{0x06} // prefix for each key to a candidate
DelegatorBondKeyPrefix = []byte{0x07} // prefix for each key to a delegator's bond
DelegatorBondKeyPrefix = []byte{0x05} // prefix for each key to a delegator's bond
)
// XXX remove beggining word get from all these keys
// GetCandidateKey - get the key for the candidate with address
// get the key for the candidate with address
func GetCandidateKey(addr sdk.Address) []byte {
return append(CandidateKeyPrefix, addr.Bytes()...)
return append(CandidatesKey, addr.Bytes()...)
}
// GetValidatorKey - get the key for the validator used in the power-store
// get the key for the validator used in the power-store
func GetValidatorKey(addr sdk.Address, power sdk.Rat, cdc *wire.Codec) []byte {
b, _ := cdc.MarshalBinary(power) // TODO need to handle error here?
return append(ValidatorKeyPrefix, append(b, addr.Bytes()...)...) // TODO does this need prefix if its in its own store
b, err := cdc.MarshalBinary(power)
if err != nil {
panic(err)
}
return append(ValidatorsKey, append(b, addr.Bytes()...)...)
}
// GetValidatorUpdatesKey - get the key for the validator used in the power-store
func GetValidatorUpdatesKey(addr sdk.Address) []byte {
return append(ValidatorUpdatesKeyPrefix, addr.Bytes()...) // TODO does this need prefix if its in its own store
// get the key for the accumulated update validators
func GetAccUpdateValidatorKey(addr sdk.Address) []byte {
return append(AccUpdateValidatorsKey, addr.Bytes()...)
}
// GetDelegatorBondKey - get the key for delegator bond with candidate
// get the key for the accumulated update validators
func GetRecentValidatorKey(addr sdk.Address) []byte {
return append(RecentValidatorsKey, addr.Bytes()...)
}
// get the key for delegator bond with candidate
func GetDelegatorBondKey(delegatorAddr, candidateAddr sdk.Address, cdc *wire.Codec) []byte {
return append(GetDelegatorBondsKey(delegatorAddr, cdc), candidateAddr.Bytes()...)
}
// GetDelegatorBondKeyPrefix - get the prefix for a delegator for all candidates
// get the prefix for a delegator for all candidates
func GetDelegatorBondsKey(delegatorAddr sdk.Address, cdc *wire.Codec) []byte {
res, err := cdc.MarshalBinary(&delegatorAddr)
if err != nil {