staking refactor compiling

This commit is contained in:
rigelrozanski 2018-05-10 19:02:35 -04:00
parent 6d0c788185
commit 675dc5df15
13 changed files with 316 additions and 284 deletions

View File

@ -6,8 +6,13 @@ BREAKING CHANGES
* Queries against the store must be prefixed with the path "/store"
* RecentValidator store now take pubkey instead of address, is sorted like Tendermint by pk's address
* RecentValidator store now take pubkey instead of address, is sorted like Tendermint by pk's address
* `gaiacli query candidate` takes and argument instead of using the `--address-candidate` flag
* Staking refactor
* store names more understandable
* removed temporary ToKick store
* removed distinction between candidates and validators
* everything is now a validator
* only validators with a status == bonded are actively validating/receiving rewards
FEATURES
@ -17,6 +22,8 @@ FEATURES
* Transactions which run out of gas stop execution and revert state changes
* A "simulate" query has been added to determine how much gas a transaction will need
* Modules can include their own gas costs for execution of particular message types
* Seperation of fee distribution to a new module
* Creation of a validator/delegation generics in `/types`
## 0.17.0 (May 15, 2018)

View File

@ -14,6 +14,7 @@ import (
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
feed "github.com/cosmos/cosmos-sdk/x/fee_distribution"
"github.com/cosmos/cosmos-sdk/x/ibc"
"github.com/cosmos/cosmos-sdk/x/stake"
)
@ -81,7 +82,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp {
app.SetInitChainer(app.initChainer)
app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper))
app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake)
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.stakeKeeper.FeeHandler))
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, feed.BurnFeeHandler))
err := app.LoadLatestVersion(app.keyMain)
if err != nil {
cmn.Exit(err.Error())

View File

@ -160,9 +160,9 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso
// add the validator
if len(genTx.Name) > 0 {
desc := stake.NewDescription(genTx.Name, "", "", "")
candidate := stake.NewCandidate(genTx.Address, genTx.PubKey, desc)
candidate.BondedShares = sdk.NewRat(freeFermionVal)
stakeData.Candidates = append(stakeData.Candidates, candidate)
validator := stake.NewValidator(genTx.Address, genTx.PubKey, desc)
validator.BondedShares = sdk.NewRat(freeFermionVal)
stakeData.Validators = append(stakeData.Validators, validator)
// pool logic
stakeData.Pool.TotalSupply += freeFermionVal

View File

@ -45,8 +45,8 @@ func main() {
rootCmd.AddCommand(
client.GetCommands(
authcmd.GetAccountCmd("acc", cdc, authcmd.GetAccountDecoder(cdc)),
stakecmd.GetCmdQueryCandidate("stake", cdc),
stakecmd.GetCmdQueryCandidates("stake", cdc),
stakecmd.GetCmdQueryValidator("stake", cdc),
stakecmd.GetCmdQueryValidators("stake", cdc),
stakecmd.GetCmdQueryDelegation("stake", cdc),
stakecmd.GetCmdQueryDelegations("stake", cdc),
)...)

View File

@ -18,11 +18,11 @@ const (
// validator for a delegated proof of stake system
type Validator interface {
Status() ValidatorStatus // status of the validator
GetOwner() Address // owner address to receive/return validators coins
GetPubKey() crypto.PubKey // validation pubkey
GetPower() Rat // validation power
GetBondHeight() int64 // height in which the validator became active
GetStatus() ValidatorStatus // status of the validator
GetAddress() Address // owner address to receive/return validators coins
GetPubKey() crypto.PubKey // validation pubkey
GetPower() Rat // validation power
GetBondHeight() int64 // height in which the validator became active
}
// validator which fulfills abci validator interface for use in Tendermint
@ -35,9 +35,9 @@ func ABCIValidator(v Validator) abci.Validator {
// properties for the set of all validators
type ValidatorSet interface {
IterateValidatorsBonded(func(index int64, validator Validator)) // execute arbitrary logic for each validator
Validator(Context, Address) Validator // get a particular validator by owner address
TotalPower(Context) Rat // total power of the validator set
IterateValidatorsBonded(Context, func(index int64, validator Validator)) // execute arbitrary logic for each validator
Validator(Context, Address) Validator // get a particular validator by owner address
TotalPower(Context) Rat // total power of the validator set
}
//_______________________________________________________________________________
@ -53,5 +53,5 @@ type Delegation interface {
type DelegationSet interface {
// execute arbitrary logic for each validator which a delegator has a delegation for
IterateDelegators(delegator Address, fn func(index int64, delegation Delegation))
IterateDelegators(Context, delegator Address, fn func(index int64, delegation Delegation))
}

View File

@ -0,0 +1,91 @@
package stake
//// keeper of the staking store
//type Keeper struct {
//storeKey sdk.StoreKey
//cdc *wire.Codec
//coinKeeper bank.Keeper
//// codespace
//codespace sdk.CodespaceType
//}
//func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper {
//keeper := Keeper{
//storeKey: key,
//cdc: cdc,
//coinKeeper: ck,
//codespace: codespace,
//}
//return keeper
//}
////_________________________________________________________________________
//// cummulative power of the non-absent prevotes
//func (k Keeper) GetTotalPrecommitVotingPower(ctx sdk.Context) sdk.Rat {
//store := ctx.KVStore(k.storeKey)
//// get absent prevote indexes
//absents := ctx.AbsentValidators()
//TotalPower := sdk.ZeroRat()
//i := int32(0)
//iterator := store.SubspaceIterator(ValidatorsBondedKey)
//for ; iterator.Valid(); iterator.Next() {
//skip := false
//for j, absentIndex := range absents {
//if absentIndex > i {
//break
//}
//// if non-voting validator found, skip adding its power
//if absentIndex == i {
//absents = append(absents[:j], absents[j+1:]...) // won't need again
//skip = true
//break
//}
//}
//if skip {
//continue
//}
//bz := iterator.Value()
//var validator Validator
//k.cdc.MustUnmarshalBinary(bz, &validator)
//TotalPower = TotalPower.Add(validator.Power)
//i++
//}
//iterator.Close()
//return TotalPower
//}
////_______________________________________________________________________
//// XXX TODO trim functionality
//// retrieve all the power changes which occur after a height
//func (k Keeper) GetPowerChangesAfterHeight(ctx sdk.Context, earliestHeight int64) (pcs []PowerChange) {
//store := ctx.KVStore(k.storeKey)
//iterator := store.SubspaceIterator(PowerChangeKey) //smallest to largest
//for ; iterator.Valid(); iterator.Next() {
//pcBytes := iterator.Value()
//var pc PowerChange
//k.cdc.MustUnmarshalBinary(pcBytes, &pc)
//if pc.Height < earliestHeight {
//break
//}
//pcs = append(pcs, pc)
//}
//iterator.Close()
//return
//}
//// set a power change
//func (k Keeper) setPowerChange(ctx sdk.Context, pc PowerChange) {
//store := ctx.KVStore(k.storeKey)
//b := k.cdc.MustMarshalBinary(pc)
//store.Set(GetPowerChangeKey(pc.Height), b)
//}

View File

@ -7,66 +7,66 @@ import (
// burn burn burn
func BurnFeeHandler(ctx sdk.Context, collectedFees sdk.Coins) {}
// Handle fee distribution to the validators and delegators
func (k Keeper) FeeHandler(ctx sdk.Context, collectedFees sdk.Coins) {
pool := k.GetPool(ctx)
params := k.GetParams(ctx)
//// Handle fee distribution to the validators and delegators
//func (k Keeper) FeeHandler(ctx sdk.Context, collectedFees sdk.Coins) {
//pool := k.GetPool(ctx)
//params := k.GetParams(ctx)
// XXX determine
candidate := NewCandidate(addrs[0], pks[0], Description{})
//// XXX determine
//candidate := NewCandidate(addrs[0], pks[0], Description{})
// calculate the proposer reward
precommitPower := k.GetTotalPrecommitVotingPower(ctx)
toProposer := coinsMulRat(collectedFees, (sdk.NewRat(1, 100).Add(sdk.NewRat(4, 100).Mul(precommitPower).Quo(pool.BondedShares))))
candidate.ProposerRewardPool = candidate.ProposerRewardPool.Plus(toProposer)
//// calculate the proposer reward
//precommitPower := k.GetTotalPrecommitVotingPower(ctx)
//toProposer := coinsMulRat(collectedFees, (sdk.NewRat(1, 100).Add(sdk.NewRat(4, 100).Mul(precommitPower).Quo(pool.BondedShares))))
//candidate.ProposerRewardPool = candidate.ProposerRewardPool.Plus(toProposer)
toReservePool := coinsMulRat(collectedFees, params.ReservePoolFee)
pool.FeeReservePool = pool.FeeReservePool.Plus(toReservePool)
//toReservePool := coinsMulRat(collectedFees, params.ReservePoolFee)
//pool.FeeReservePool = pool.FeeReservePool.Plus(toReservePool)
distributedReward := (collectedFees.Minus(toProposer)).Minus(toReservePool)
pool.FeePool = pool.FeePool.Plus(distributedReward)
pool.FeeSumReceived = pool.FeeSumReceived.Plus(distributedReward)
pool.FeeRecent = distributedReward
//distributedReward := (collectedFees.Minus(toProposer)).Minus(toReservePool)
//pool.FeePool = pool.FeePool.Plus(distributedReward)
//pool.FeeSumReceived = pool.FeeSumReceived.Plus(distributedReward)
//pool.FeeRecent = distributedReward
// lastly update the FeeRecent term
pool.FeeRecent = collectedFees
//// lastly update the FeeRecent term
//pool.FeeRecent = collectedFees
k.setPool(ctx, pool)
}
//k.setPool(ctx, pool)
//}
func coinsMulRat(coins sdk.Coins, rat sdk.Rat) sdk.Coins {
var res sdk.Coins
for _, coin := range coins {
coinMulAmt := rat.Mul(sdk.NewRat(coin.Amount)).Evaluate()
coinMul := sdk.Coins{{coin.Denom, coinMulAmt}}
res = res.Plus(coinMul)
}
return res
}
//func coinsMulRat(coins sdk.Coins, rat sdk.Rat) sdk.Coins {
//var res sdk.Coins
//for _, coin := range coins {
//coinMulAmt := rat.Mul(sdk.NewRat(coin.Amount)).Evaluate()
//coinMul := sdk.Coins{{coin.Denom, coinMulAmt}}
//res = res.Plus(coinMul)
//}
//return res
//}
//____________________________________________________________________________-
////____________________________________________________________________________-
// calculate adjustment changes for a candidate at a height
func CalculateAdjustmentChange(candidate Candidate, pool Pool, denoms []string, height int64) (Candidate, Pool) {
//// calculate adjustment changes for a candidate at a height
//func CalculateAdjustmentChange(candidate Candidate, pool Pool, denoms []string, height int64) (Candidate, Pool) {
heightRat := sdk.NewRat(height)
lastHeightRat := sdk.NewRat(height - 1)
candidateFeeCount := candidate.BondedShares.Mul(heightRat)
poolFeeCount := pool.BondedShares.Mul(heightRat)
//heightRat := sdk.NewRat(height)
//lastHeightRat := sdk.NewRat(height - 1)
//candidateFeeCount := candidate.BondedShares.Mul(heightRat)
//poolFeeCount := pool.BondedShares.Mul(heightRat)
for i, denom := range denoms {
poolFeeSumReceived := sdk.NewRat(pool.FeeSumReceived.AmountOf(denom))
poolFeeRecent := sdk.NewRat(pool.FeeRecent.AmountOf(denom))
// calculate simple and projected pools
simplePool := candidateFeeCount.Quo(poolFeeCount).Mul(poolFeeSumReceived)
calc1 := candidate.PrevBondedShares.Mul(lastHeightRat).Quo(pool.PrevBondedShares.Mul(lastHeightRat)).Mul(poolFeeRecent)
calc2 := candidate.BondedShares.Quo(pool.BondedShares).Mul(poolFeeRecent)
projectedPool := calc1.Add(calc2)
//for i, denom := range denoms {
//poolFeeSumReceived := sdk.NewRat(pool.FeeSumReceived.AmountOf(denom))
//poolFeeRecent := sdk.NewRat(pool.FeeRecent.AmountOf(denom))
//// calculate simple and projected pools
//simplePool := candidateFeeCount.Quo(poolFeeCount).Mul(poolFeeSumReceived)
//calc1 := candidate.PrevBondedShares.Mul(lastHeightRat).Quo(pool.PrevBondedShares.Mul(lastHeightRat)).Mul(poolFeeRecent)
//calc2 := candidate.BondedShares.Quo(pool.BondedShares).Mul(poolFeeRecent)
//projectedPool := calc1.Add(calc2)
AdjustmentChange := simplePool.Sub(projectedPool)
candidate.FeeAdjustments[i] = candidate.FeeAdjustments[i].Add(AdjustmentChange)
pool.FeeAdjustments[i] = pool.FeeAdjustments[i].Add(AdjustmentChange)
}
//AdjustmentChange := simplePool.Sub(projectedPool)
//candidate.FeeAdjustments[i] = candidate.FeeAdjustments[i].Add(AdjustmentChange)
//pool.FeeAdjustments[i] = pool.FeeAdjustments[i].Add(AdjustmentChange)
//}
return candidate, pool
}
//return candidate, pool
//}

View File

@ -1,113 +1,107 @@
package stake
import (
"encoding/binary"
//// GenesisState - all staking state that must be provided at genesis
//type GenesisState struct {
//Pool Pool `json:"pool"`
//Params Params `json:"params"`
//}
sdk "github.com/cosmos/cosmos-sdk/types"
)
//func NewGenesisState(pool Pool, params Params, candidates []Candidate, bonds []Delegation) GenesisState {
//return GenesisState{
//Pool: pool,
//Params: params,
//}
//}
// GenesisState - all staking state that must be provided at genesis
type GenesisState struct {
Pool Pool `json:"pool"`
Params Params `json:"params"`
}
//// get raw genesis raw message for testing
//func DefaultGenesisState() GenesisState {
//return GenesisState{
//Pool: initialPool(),
//Params: defaultParams(),
//}
//}
func NewGenesisState(pool Pool, params Params, candidates []Candidate, bonds []Delegation) GenesisState {
return GenesisState{
Pool: pool,
Params: params,
}
}
//// fee information for a validator
//type Validator struct {
//Adjustments []sdk.Rat `json:"fee_adjustments"` // XXX Adjustment factors for lazy fee accounting, couples with Params.BondDenoms
//PrevBondedShares sdk.Rat `json:"prev_bonded_shares"` // total shares of a global hold pools
//}
// get raw genesis raw message for testing
func DefaultGenesisState() GenesisState {
return GenesisState{
Pool: initialPool(),
Params: defaultParams(),
}
}
////_________________________________________________________________________
// fee information for a validator
type Validator struct {
Adjustments []sdk.Rat `json:"fee_adjustments"` // XXX Adjustment factors for lazy fee accounting, couples with Params.BondDenoms
PrevBondedShares sdk.Rat `json:"prev_bonded_shares"` // total shares of a global hold pools
}
//// Params defines the high level settings for staking
//type Params struct {
//FeeDenoms []string `json:"fee_denoms"` // accepted fee denoms
//ReservePoolFee sdk.Rat `json:"reserve_pool_fee"` // percent of fees which go to reserve pool
//}
//_________________________________________________________________________
//func (p Params) equal(p2 Params) bool {
//return p.BondDenom == p2.BondDenom &&
//p.ReservePoolFee.Equal(p2.ReservePoolFee)
//}
// Params defines the high level settings for staking
type Params struct {
FeeDenoms []string `json:"fee_denoms"` // accepted fee denoms
ReservePoolFee sdk.Rat `json:"reserve_pool_fee"` // percent of fees which go to reserve pool
}
//func defaultParams() Params {
//return Params{
//FeeDenoms: []string{"steak"},
//ReservePoolFee: sdk.NewRat(5, 100),
//}
//}
func (p Params) equal(p2 Params) bool {
return p.BondDenom == p2.BondDenom &&
p.ReservePoolFee.Equal(p2.ReservePoolFee)
}
////_________________________________________________________________________
func defaultParams() Params {
return Params{
FeeDenoms: []string{"steak"},
ReservePoolFee: sdk.NewRat(5, 100),
}
}
//// Pool - dynamic parameters of the current state
//type Pool struct {
//FeeReservePool sdk.Coins `json:"fee_reserve_pool"` // XXX reserve pool of collected fees for use by governance
//FeePool sdk.Coins `json:"fee_pool"` // XXX fee pool for all the fee shares which have already been distributed
//FeeSumReceived sdk.Coins `json:"fee_sum_received"` // XXX sum of all fees received, post reserve pool `json:"fee_sum_received"`
//FeeRecent sdk.Coins `json:"fee_recent"` // XXX most recent fee collected
//FeeAdjustments []sdk.Rat `json:"fee_adjustments"` // XXX Adjustment factors for lazy fee accounting, couples with Params.BondDenoms
//PrevBondedShares sdk.Rat `json:"prev_bonded_shares"` // XXX last recorded bonded shares
//}
//_________________________________________________________________________
//func (p Pool) equal(p2 Pool) bool {
//return p.FeeReservePool.IsEqual(p2.FeeReservePool) &&
//p.FeePool.IsEqual(p2.FeePool) &&
//p.FeeSumReceived.IsEqual(p2.FeeSumReceived) &&
//p.FeeRecent.IsEqual(p2.FeeRecent) &&
//sdk.RatsEqual(p.FeeAdjustments, p2.FeeAdjustments) &&
//p.PrevBondedShares.Equal(p2.PrevBondedShares)
//}
// Pool - dynamic parameters of the current state
type Pool struct {
FeeReservePool sdk.Coins `json:"fee_reserve_pool"` // XXX reserve pool of collected fees for use by governance
FeePool sdk.Coins `json:"fee_pool"` // XXX fee pool for all the fee shares which have already been distributed
FeeSumReceived sdk.Coins `json:"fee_sum_received"` // XXX sum of all fees received, post reserve pool `json:"fee_sum_received"`
FeeRecent sdk.Coins `json:"fee_recent"` // XXX most recent fee collected
FeeAdjustments []sdk.Rat `json:"fee_adjustments"` // XXX Adjustment factors for lazy fee accounting, couples with Params.BondDenoms
PrevBondedShares sdk.Rat `json:"prev_bonded_shares"` // XXX last recorded bonded shares
}
//// initial pool for testing
//func initialPool() Pool {
//return Pool{
//FeeReservePool: sdk.Coins(nil),
//FeePool: sdk.Coins(nil),
//FeeSumReceived: sdk.Coins(nil),
//FeeRecent: sdk.Coins(nil),
//FeeAdjustments: []sdk.Rat{sdk.ZeroRat()},
//PrevBondedShares: sdk.ZeroRat(),
//}
//}
func (p Pool) equal(p2 Pool) bool {
return p.FeeReservePool.IsEqual(p2.FeeReservePool) &&
p.FeePool.IsEqual(p2.FeePool) &&
p.FeeSumReceived.IsEqual(p2.FeeSumReceived) &&
p.FeeRecent.IsEqual(p2.FeeRecent) &&
sdk.RatsEqual(p.FeeAdjustments, p2.FeeAdjustments) &&
p.PrevBondedShares.Equal(p2.PrevBondedShares)
}
////_________________________________________________________________________
// initial pool for testing
func initialPool() Pool {
return Pool{
FeeReservePool: sdk.Coins(nil),
FeePool: sdk.Coins(nil),
FeeSumReceived: sdk.Coins(nil),
FeeRecent: sdk.Coins(nil),
FeeAdjustments: []sdk.Rat{sdk.ZeroRat()},
PrevBondedShares: sdk.ZeroRat(),
}
}
//// Used in calculation of fee shares, added to a queue for each block where a power change occures
//type PowerChange struct {
//Height int64 `json:"height"` // block height at change
//Power sdk.Rat `json:"power"` // total power at change
//PrevPower sdk.Rat `json:"prev_power"` // total power at previous height-1
//FeesIn sdk.Coins `json:"fees_in"` // fees in at block height
//PrevFeePool sdk.Coins `json:"prev_fee_pool"` // total fees in at previous block height
//}
//_________________________________________________________________________
////_________________________________________________________________________
//// KEY MANAGEMENT
// Used in calculation of fee shares, added to a queue for each block where a power change occures
type PowerChange struct {
Height int64 `json:"height"` // block height at change
Power sdk.Rat `json:"power"` // total power at change
PrevPower sdk.Rat `json:"prev_power"` // total power at previous height-1
FeesIn sdk.Coins `json:"fees_in"` // fees in at block height
PrevFeePool sdk.Coins `json:"prev_fee_pool"` // total fees in at previous block height
}
//var (
//// Keys for store prefixes
//PowerChangeKey = []byte{0x09} // prefix for power change object
//)
//_________________________________________________________________________
// KEY MANAGEMENT
var (
// Keys for store prefixes
PowerChangeKey = []byte{0x09} // prefix for power change object
)
// get the key for the accumulated update validators
func GetPowerChangeKey(height int64) []byte {
heightBytes := make([]byte, binary.MaxVarintLen64)
binary.BigEndian.PutUint64(heightBytes, ^uint64(height)) // invert height (older validators first)
return append(PowerChangeKey, heightBytes...)
}
//// get the key for the accumulated update validators
//func GetPowerChangeKey(height int64) []byte {
//heightBytes := make([]byte, binary.MaxVarintLen64)
//binary.BigEndian.PutUint64(heightBytes, ^uint64(height)) // invert height (older validators first)
//return append(PowerChangeKey, heightBytes...)
//}

View File

@ -3,7 +3,6 @@ package stake
import (
"bytes"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/bank"
@ -77,8 +76,8 @@ func (k Keeper) setValidator(ctx sdk.Context, validator Validator) {
// if found, copy the old block height and counter
if oldFound {
validator.ValidatorBondHeight = oldValidator.ValidatorBondHeight
validator.ValidatorBondCounter = oldValidator.ValidatorBondCounter
validator.BondHeight = oldValidator.BondHeight
validator.BondIntraTxCounter = oldValidator.BondIntraTxCounter
}
// marshal the validator record and add to the state
@ -93,9 +92,9 @@ func (k Keeper) setValidator(ctx sdk.Context, validator Validator) {
// if this validator wasn't just bonded then update the height and counter
if oldValidator.Status != sdk.Bonded {
validator.ValidatorBondHeight = ctx.BlockHeight()
validator.BondHeight = ctx.BlockHeight()
counter := k.getIntraTxCounter(ctx)
validator.ValidatorBondCounter = counter
validator.BondIntraTxCounter = counter
k.setIntraTxCounter(ctx, counter+1)
}
@ -205,7 +204,7 @@ func (k Keeper) GetValidatorsBondedByPower(ctx sdk.Context) []Validator {
func (k Keeper) addNewValidatorOrNot(ctx sdk.Context, store sdk.KVStore, address sdk.Address) {
// clear the current validators store, add to the ToKickOut temp store
toKickOut := make(map[[]byte][]byte) // map[key]value
toKickOut := make(map[string][]byte) // map[key]value
iterator := store.SubspaceIterator(ValidatorsBondedKey)
for ; iterator.Valid(); iterator.Next() {
@ -216,7 +215,7 @@ func (k Keeper) addNewValidatorOrNot(ctx sdk.Context, store sdk.KVStore, address
addr := validator.Address
// iterator.Value is the validator object
toKickOut[addr] = iterator.Value()
toKickOut[string(addr)] = iterator.Value()
store.Delete(iterator.Key())
}
iterator.Close()
@ -235,7 +234,7 @@ func (k Keeper) addNewValidatorOrNot(ctx sdk.Context, store sdk.KVStore, address
k.cdc.MustUnmarshalBinary(bz, &validator)
// remove from ToKickOut group
toKickOut[validator.Address] = nil
toKickOut[string(validator.Address)] = nil
// also add to the current validators group
store.Set(GetValidatorsBondedBondedKey(validator.PubKey), bz)
@ -251,7 +250,7 @@ func (k Keeper) addNewValidatorOrNot(ctx sdk.Context, store sdk.KVStore, address
// add any kicked out validators to the accumulated changes for tendermint
for key, value := range toKickOut {
addr := AddrFromKey(key)
addr := AddrFromKey([]byte(key))
var validator Validator
k.cdc.MustUnmarshalBinary(value, &validator)
@ -260,45 +259,6 @@ func (k Keeper) addNewValidatorOrNot(ctx sdk.Context, store sdk.KVStore, address
}
}
// cummulative power of the non-absent prevotes
//func (k Keeper) GetTotalPrecommitVotingPower(ctx sdk.Context) sdk.Rat {
//store := ctx.KVStore(k.storeKey)
//// get absent prevote indexes
//absents := ctx.AbsentValidators()
//TotalPower := sdk.ZeroRat()
//i := int32(0)
//iterator := store.SubspaceIterator(ValidatorsBondedKey)
//for ; iterator.Valid(); iterator.Next() {
//skip := false
//for j, absentIndex := range absents {
//if absentIndex > i {
//break
//}
//// if non-voting validator found, skip adding its power
//if absentIndex == i {
//absents = append(absents[:j], absents[j+1:]...) // won't need again
//skip = true
//break
//}
//}
//if skip {
//continue
//}
//bz := iterator.Value()
//var validator Validator
//k.cdc.MustUnmarshalBinary(bz, &validator)
//TotalPower = TotalPower.Add(validator.Power)
//i++
//}
//iterator.Close()
//return TotalPower
//}
//_________________________________________________________________________
// Accumulated updates to the active/bonded validator set for tendermint
@ -401,35 +361,6 @@ func (k Keeper) removeDelegation(ctx sdk.Context, bond Delegation) {
//_______________________________________________________________________
// XXX TODO trim functionality
// retrieve all the power changes which occur after a height
func (k Keeper) GetPowerChangesAfterHeight(ctx sdk.Context, earliestHeight int64) (pcs []PowerChange) {
store := ctx.KVStore(k.storeKey)
iterator := store.SubspaceIterator(PowerChangeKey) //smallest to largest
for ; iterator.Valid(); iterator.Next() {
pcBytes := iterator.Value()
var pc PowerChange
k.cdc.MustUnmarshalBinary(pcBytes, &pc)
if pc.Height < earliestHeight {
break
}
pcs = append(pcs, pc)
}
iterator.Close()
return
}
// set a power change
func (k Keeper) setPowerChange(ctx sdk.Context, pc PowerChange) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(pc)
store.Set(GetPowerChangeKey(pc.Height), b)
}
//_______________________________________________________________________
// load/save the global staking params
func (k Keeper) GetParams(ctx sdk.Context) (params Params) {
// check if cached before anything
@ -483,10 +414,10 @@ func (k Keeper) setPool(ctx sdk.Context, p Pool) {
var _ sdk.ValidatorSet = Keeper{}
// iterate through the active validator set and perform the provided function
func (k Keeper) IterateValidatorsBonded(fn func(index int64, validator sdk.Validator)) {
func (k Keeper) IterateValidatorsBonded(ctx sdk.Context, fn func(index int64, validator sdk.Validator)) {
store := ctx.KVStore(k.storeKey)
iterator := store.SubspaceIterator(ValidatorsBondedKey)
i := 0
i := int64(0)
for ; iterator.Valid(); iterator.Next() {
bz := iterator.Value()
var validator Validator
@ -528,15 +459,16 @@ func (k Keeper) Delegation(ctx sdk.Context, addrDel sdk.Address, addrVal sdk.Add
}
// iterate through the active validator set and perform the provided function
func (k Keeper) IterateDelegators(delAddr sdk.Address, fn func(index int64, delegator sdk.Delegator)) {
func (k Keeper) IterateDelegators(ctx sdk.Context, delAddr sdk.Address, fn func(index int64, delegation sdk.Delegation)) {
store := ctx.KVStore(k.storeKey)
key := GetDelegationsKey(delAddr, k.cdc)
iterator := store.SubspaceIterator(ValidatorsBondedKey)
i := 0
iterator := store.SubspaceIterator(key)
i := int64(0)
for ; iterator.Valid(); iterator.Next() {
bz := iterator.Value()
var delegation Delegation
k.cdc.MustUnmarshalBinary(bz, &delegation)
fn(i, delegator) // XXX is this safe will the fields be able to get written to?
fn(i, delegation) // XXX is this safe will the fields be able to get written to?
i++
}
iterator.Close()

View File

@ -32,14 +32,14 @@ func GetValidatorKey(addr sdk.Address) []byte {
// get the key for the validator used in the power-store
func GetValidatorsBondedByPowerKey(validator Validator) []byte {
powerBytes := []byte(validator.Power.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first)
powerBytes := []byte(validator.BondedShares.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first)
// TODO ensure that the key will be a readable string.. probably should add seperators and have
// heightBytes and counterBytes represent strings like powerBytes does
heightBytes := make([]byte, binary.MaxVarintLen64)
binary.BigEndian.PutUint64(heightBytes, ^uint64(validator.Height)) // invert height (older validators first)
binary.BigEndian.PutUint64(heightBytes, ^uint64(validator.BondHeight)) // invert height (older validators first)
counterBytes := make([]byte, 2)
binary.BigEndian.PutUint16(counterBytes, ^uint16(validator.Counter)) // invert counter (first txns have priority)
binary.BigEndian.PutUint16(counterBytes, ^uint16(validator.BondIntraTxCounter)) // invert counter (first txns have priority)
return append(ValidatorsByPowerKey,
append(powerBytes,
append(heightBytes,

View File

@ -319,7 +319,7 @@ func TestGetValidatorsBondedEdgeCases(t *testing.T) {
require.Equal(t, validators[3].Address, validators[1].Address, "%v", validators)
validator, exists := keeper.GetValidator(ctx, validators[4].Address)
require.Equal(t, exists, true)
require.Equal(t, validator.ValidatorBondHeight, int64(40))
require.Equal(t, validator.BondHeight, int64(40))
//If two validators both increase to the same voting power in the same block,
//the one with the first transaction should take precedence (become a validator).

View File

@ -34,7 +34,7 @@ func (p Pool) bondedToUnbondedPool(validator Validator) (Pool, Validator) {
// replace bonded shares with unbonded shares
p, tokens := p.removeSharesBonded(validator.BondedShares)
p, validator.BondedShares = p.addTokensUnbonded(tokens)
validator.Status = Unbonded
validator.Status = sdk.Unbonded
return p, validator
}
@ -44,7 +44,7 @@ func (p Pool) unbondedToBondedPool(validator Validator) (Pool, Validator) {
// replace unbonded shares with bonded shares
p, tokens := p.removeSharesUnbonded(validator.BondedShares)
p, validator.BondedShares = p.addTokensBonded(tokens)
validator.Status = Bonded
validator.Status = sdk.Bonded
return p, validator
}
@ -87,7 +87,7 @@ func (p Pool) validatorAddTokens(validator Validator,
exRate := validator.delegatorShareExRate()
var receivedGlobalShares sdk.Rat
if validator.Status == Bonded {
if validator.Status == sdk.Bonded {
p, receivedGlobalShares = p.addTokensBonded(amount)
} else {
p, receivedGlobalShares = p.addTokensUnbonded(amount)
@ -107,7 +107,7 @@ func (p Pool) validatorRemoveShares(validator Validator,
//exRate := validator.delegatorShareExRate() //XXX make sure not used
globalPoolSharesToRemove := validator.delegatorShareExRate().Mul(shares)
if validator.Status == Bonded {
if validator.Status == sdk.Bonded {
p, createdCoins = p.removeSharesBonded(globalPoolSharesToRemove)
} else {
p, createdCoins = p.removeSharesUnbonded(globalPoolSharesToRemove)

View File

@ -127,17 +127,17 @@ func initialPool() Pool {
// exchange rate.
type Validator struct {
Status sdk.ValidatorStatus `json:"status"` // Bonded status
Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here
Address sdk.Address `json:"address"` // Sender of BondTx - UnbondTx returns here
PubKey crypto.PubKey `json:"pub_key"` // Pubkey of validator
BondedShares sdk.Rat `json:"bonded_shares"` // total shares of a global hold pools
UnbondingShares sdk.Rat `json:"unbonding_shares"` // total shares of a global hold pools
UnbondedShares sdk.Rat `json:"unbonded_shares"` // total shares of a global hold pools
BondedShares sdk.Rat `json:"bonded_shares"` // total shares of bonded global hold pool
UnbondingShares sdk.Rat `json:"unbonding_shares"` // total shares of unbonding global hold pool
UnbondedShares sdk.Rat `json:"unbonded_shares"` // total shares of unbonded global hold pool
DelegatorShares sdk.Rat `json:"liabilities"` // total shares issued to a validator's delegators
Description Description `json:"description"` // Description terms for the validator
ValidatorBondHeight int64 `json:"validator_bond_height"` // Earliest height as a bonded validator
ValidatorBondCounter int16 `json:"validator_bond_counter"` // Block-local tx index of validator change
ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer
Description Description `json:"description"` // Description terms for the validator
BondHeight int64 `json:"validator_bond_height"` // Earliest height as a bonded validator
BondIntraTxCounter int16 `json:"validator_bond_counter"` // Block-local tx index of validator change
ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer
Commission sdk.Rat `json:"commission"` // XXX the commission rate of fees charged to any delegators
CommissionMax sdk.Rat `json:"commission_max"` // XXX maximum commission rate which this validator can ever charge
@ -154,21 +154,20 @@ type Validators []Validator
// NewValidator - initialize a new validator
func NewValidator(address sdk.Address, pubKey crypto.PubKey, description Description) Validator {
return Validator{
Status: Unbonded,
Address: address,
PubKey: pubKey,
BondedShares: sdk.ZeroRat(),
DelegatorShares: sdk.ZeroRat(),
Description: description,
ValidatorBondHeight: int64(0),
ValidatorBondIntraTxCounter: int16(0),
ProposerRewardPool: sdk.Coins{},
Commission: sdk.ZeroRat(),
CommissionMax: sdk.ZeroRat(),
CommissionChangeRate: sdk.ZeroRat(),
CommissionChangeToday: sdk.ZeroRat(),
FeeAdjustments: []sdk.Rat(nil),
PrevBondedShares: sdk.ZeroRat(),
Status: sdk.Unbonded,
Address: address,
PubKey: pubKey,
BondedShares: sdk.ZeroRat(),
DelegatorShares: sdk.ZeroRat(),
Description: description,
BondHeight: int64(0),
BondIntraTxCounter: int16(0),
ProposerRewardPool: sdk.Coins{},
Commission: sdk.ZeroRat(),
CommissionMax: sdk.ZeroRat(),
CommissionChangeRate: sdk.ZeroRat(),
CommissionChangeToday: sdk.ZeroRat(),
PrevBondedShares: sdk.ZeroRat(),
}
}
@ -179,14 +178,13 @@ func (v Validator) equal(c2 Validator) bool {
v.BondedShares.Equal(c2.BondedShares) &&
v.DelegatorShares.Equal(c2.DelegatorShares) &&
v.Description == c2.Description &&
v.ValidatorBondHeight == c2.ValidatorBondHeight &&
//v.ValidatorBondCounter == c2.ValidatorBondCounter && // counter is always changing
v.BondHeight == c2.BondHeight &&
//v.BondIntraTxCounter == c2.BondIntraTxCounter && // counter is always changing
v.ProposerRewardPool.IsEqual(c2.ProposerRewardPool) &&
v.Commission.Equal(c2.Commission) &&
v.CommissionMax.Equal(c2.CommissionMax) &&
v.CommissionChangeRate.Equal(c2.CommissionChangeRate) &&
v.CommissionChangeToday.Equal(c2.CommissionChangeToday) &&
sdk.RatsEqual(v.FeeAdjustments, c2.FeeAdjustments) &&
v.PrevBondedShares.Equal(c2.PrevBondedShares)
}
@ -212,14 +210,21 @@ func (v Validator) delegatorShareExRate() sdk.Rat {
if v.DelegatorShares.IsZero() {
return sdk.OneRat()
}
return v.BondedShares.Quo(v.DelegatorShares)
switch v.Status {
case sdk.Bonded:
return v.BondedShares.Quo(v.DelegatorShares)
case sdk.Unbonding:
return v.UnbondingShares.Quo(v.DelegatorShares)
default: //sdk.Unbonded, sdk.Revoked:
return v.UnbondedShares.Quo(v.DelegatorShares)
}
}
// abci validator from stake validator type
func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator {
return abci.Validator{
PubKey: v.PubKey.Bytes(),
Power: v.Power.Evaluate(),
Power: v.BondedShares.Evaluate(),
}
}
@ -241,9 +246,11 @@ func (v Validator) abciValidatorZero(cdc *wire.Codec) abci.Validator {
var _ sdk.Validator = Validator{}
// nolint - for sdk.Validator
func (v Validator) GetAddress() sdk.Address { return v.Address }
func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey }
func (v Validator) GetPower() sdk.Rat { return v.Power }
func (v Validator) GetStatus() sdk.ValidatorStatus { return v.Status }
func (v Validator) GetAddress() sdk.Address { return v.Address }
func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey }
func (v Validator) GetPower() sdk.Rat { return v.BondedShares }
func (v Validator) GetBondHeight() int64 { return v.BondHeight }
//_________________________________________________________________________
@ -271,4 +278,4 @@ var _ sdk.Delegation = Delegation{}
// nolint - for sdk.Delegation
func (b Delegation) GetDelegator() sdk.Address { return b.DelegatorAddr }
func (b Delegation) GetValidator() sdk.Address { return b.ValidatorAddr }
func (b Delegation) GetBondAmount() sdk.Rat { return b.Shares }
func (b Delegation) GetBondShares() sdk.Rat { return b.Shares }