staking refactor compiling
This commit is contained in:
parent
6d0c788185
commit
675dc5df15
|
@ -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)
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
)...)
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
//}
|
|
@ -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
|
||||
//}
|
||||
|
|
|
@ -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...)
|
||||
//}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 }
|
||||
|
|
Loading…
Reference in New Issue