diff --git a/docs/spec/distribution/end_block.md b/docs/spec/distribution/end_block.md index 952d1832a..2b74cd3e9 100644 --- a/docs/spec/distribution/end_block.md +++ b/docs/spec/distribution/end_block.md @@ -1,7 +1,7 @@ # End Block At each endblock, the fees received are allocated to the proposer, community fund, -and global pool. When the validator is the proposer of the round, that +and pool. When the validator is the proposer of the round, that validator (and their delegators) receives between 1% and 5% of fee rewards, the reserve community tax is then charged, then the remainder is distributed proportionally by voting power to all bonded validators independent of whether @@ -15,7 +15,7 @@ pool which validator holds individually (`ValidatorDistribution.ProvisionsRewardPool`). ``` -func AllocateFees(feesCollected sdk.Coins, global Global, proposer ValidatorDistribution, +func AllocateFees(feesCollected sdk.Coins, feePool FeePool, proposer ValidatorDistribution, sumPowerPrecommitValidators, totalBondedTokens, communityTax, proposerCommissionRate sdk.Dec) @@ -28,13 +28,11 @@ func AllocateFees(feesCollected sdk.Coins, global Global, proposer ValidatorDist proposer.Pool += proposerReward - commission communityFunding = feesCollectedDec * communityTax - global.CommunityFund += communityFunding + feePool.CommunityFund += communityFunding poolReceived = feesCollectedDec - proposerReward - communityFunding - global.Pool += poolReceived - global.EverReceivedPool += poolReceived - global.LastReceivedPool = poolReceived + feePool.Pool += poolReceived SetValidatorDistribution(proposer) - SetGlobal(global) + SetFeePool(feePool) ``` diff --git a/docs/spec/distribution/overview.md b/docs/spec/distribution/overview.md index 13a4ea3f1..28b1bbedd 100644 --- a/docs/spec/distribution/overview.md +++ b/docs/spec/distribution/overview.md @@ -40,7 +40,7 @@ to independently and lazily withdraw their rewards. As a part of the lazy computations, each delegator holds an accumulation term specific to each validator which is used to estimate what their approximate -fair portion of tokens held in the global pool is owed to them. +fair portion of tokens held in the global fee pool is owed to them. ``` entitlement = delegator-accumulation / all-delegators-accumulation diff --git a/docs/spec/distribution/state.md b/docs/spec/distribution/state.md index 3e3669789..e5c0d47d0 100644 --- a/docs/spec/distribution/state.md +++ b/docs/spec/distribution/state.md @@ -1,9 +1,9 @@ ## State -### Global +### FeePool All globally tracked parameters for distribution are stored within -`Global`. Rewards are collected and added to the reward pool and +`FeePool`. Rewards are collected and added to the reward pool and distributed to validators/delegators from here. Note that the reward pool holds decimal coins (`DecCoins`) to allow @@ -11,7 +11,7 @@ for fractions of coins to be received from operations like inflation. When coins are distributed from the pool they are truncated back to `sdk.Coins` which are non-decimal. - - Global: `0x00 -> amino(global)` + - FeePool: `0x00 -> amino(FeePool)` ```golang // coins with decimal @@ -22,7 +22,7 @@ type DecCoin struct { Denom string } -type Global struct { +type FeePool struct { TotalValAccumUpdateHeight int64 // last height which the total validator accum was updated TotalValAccum sdk.Dec // total valdator accum held by validators Pool DecCoins // funds for all validators which have yet to be withdrawn @@ -42,7 +42,7 @@ Validator distribution information for the relevant validator is updated each ti ```golang type ValidatorDistInfo struct { - GlobalWithdrawalHeight int64 // last height this validator withdrew from the global pool + FewPoolWithdrawalHeight int64 // last height this validator withdrew from the global fee pool Pool DecCoins // rewards owed to delegators, commission has already been charged (includes proposer reward) PoolCommission DecCoins // commission collected by this validator (pending withdrawal) diff --git a/docs/spec/distribution/transactions.md b/docs/spec/distribution/transactions.md index 861620620..47b11165a 100644 --- a/docs/spec/distribution/transactions.md +++ b/docs/spec/distribution/transactions.md @@ -26,18 +26,18 @@ func GetDelegatorRewardsAll(delegatorAddr sdk.AccAddress, height int64) DecCoins // collect all entitled rewards withdraw = 0 pool = stake.GetPool() - global = GetGlobal() + feePool = GetFeePool() for delegation = range delegations delInfo = GetDelegationDistInfo(delegation.DelegatorAddr, delegation.ValidatorAddr) valInfo = GetValidatorDistInfo(delegation.ValidatorAddr) validator = GetValidator(delegation.ValidatorAddr) - global, diWithdraw = delInfo.WithdrawRewards(global, valInfo, height, pool.BondedTokens, + feePool, diWithdraw = delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens, validator.Tokens, validator.DelegatorShares, validator.Commission) withdraw += diWithdraw - SetGlobal(global) + SetFeePool(feePool) return withdraw ``` @@ -58,16 +58,16 @@ func WithdrawDelegationReward(delegatorAddr, validatorAddr, withdrawAddr sdk.Acc // get all distribution scenarios pool = stake.GetPool() - global = GetGlobal() + feePool = GetFeePool() delInfo = GetDelegationDistInfo(delegatorAddr, validatorAddr) valInfo = GetValidatorDistInfo(validatorAddr) validator = GetValidator(validatorAddr) - global, withdraw = delInfo.WithdrawRewards(global, valInfo, height, pool.BondedTokens, + feePool, withdraw = delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens, validator.Tokens, validator.DelegatorShares, validator.Commission) - SetGlobal(global) + SetFeePool(feePool) AddCoins(withdrawAddr, withdraw.TruncateDecimal()) ``` @@ -90,7 +90,7 @@ type TxWithdrawValidatorRewardsAll struct { func WithdrawValidatorRewardsAll(operatorAddr, withdrawAddr sdk.AccAddress) height = GetHeight() - global = GetGlobal() + feePool = GetFeePool() pool = GetPool() ValInfo = GetValidatorDistInfo(delegation.ValidatorAddr) validator = GetValidator(delegation.ValidatorAddr) @@ -99,10 +99,10 @@ func WithdrawValidatorRewardsAll(operatorAddr, withdrawAddr sdk.AccAddress) withdraw = GetDelegatorRewardsAll(validator.OperatorAddr, height) // withdrawal validator commission rewards - global, commission = valInfo.WithdrawCommission(global, valInfo, height, pool.BondedTokens, + feePool, commission = valInfo.WithdrawCommission(feePool, valInfo, height, pool.BondedTokens, validator.Tokens, validator.Commission) withdraw += commission - SetGlobal(global) + SetFeePool(feePool) AddCoins(withdrawAddr, withdraw.TruncateDecimal()) ``` @@ -117,7 +117,7 @@ block. The accum is always additive to the existing accum. This term is to be updated each time rewards are withdrawn from the system. ``` -func (g Global) UpdateTotalValAccum(height int64, totalBondedTokens Dec) Global +func (g FeePool) UpdateTotalValAccum(height int64, totalBondedTokens Dec) FeePool blocks = height - g.TotalValAccumUpdateHeight g.TotalValAccum += totalDelShares * blocks g.TotalValAccumUpdateHeight = height @@ -140,7 +140,7 @@ func (vi ValidatorDistInfo) UpdateTotalDelAccum(height int64, totalDelShares Dec return vi ``` -### Global pool to validator pool +### FeePool pool to validator pool Every time a validator or delegator executes a withdrawal or the validator is the proposer and receives new tokens, the relevant validator must move tokens @@ -148,14 +148,14 @@ from the passive global pool to their own pool. It is at this point that the commission is withdrawn ``` -func (vi ValidatorDistInfo) TakeGlobalRewards(g Global, height int64, totalBonded, vdTokens, commissionRate Dec) ( - vi ValidatorDistInfo, g Global) +func (vi ValidatorDistInfo) TakeFeePoolRewards(g FeePool, height int64, totalBonded, vdTokens, commissionRate Dec) ( + vi ValidatorDistInfo, g FeePool) g.UpdateTotalValAccum(height, totalBondedShares) // update the validators pool - blocks = height - vi.GlobalWithdrawalHeight - vi.GlobalWithdrawalHeight = height + blocks = height - vi.FeePoolWithdrawalHeight + vi.FeePoolWithdrawalHeight = height accum = blocks * vdTokens withdrawalTokens := g.Pool * accum / g.TotalValAccum commission := withdrawalTokens * commissionRate @@ -175,12 +175,12 @@ For delegations (including validator's self-delegation) all rewards from reward pool have already had the validator's commission taken away. ``` -func (di DelegatorDistInfo) WithdrawRewards(g Global, vi ValidatorDistInfo, +func (di DelegatorDistInfo) WithdrawRewards(g FeePool, vi ValidatorDistInfo, height int64, totalBonded, vdTokens, totalDelShares, commissionRate Dec) ( - di DelegatorDistInfo, g Global, withdrawn DecCoins) + di DelegatorDistInfo, g FeePool, withdrawn DecCoins) vi.UpdateTotalDelAccum(height, totalDelShares) - g = vi.TakeGlobalRewards(g, height, totalBonded, vdTokens, commissionRate) + g = vi.TakeFeePoolRewards(g, height, totalBonded, vdTokens, commissionRate) blocks = height - di.WithdrawalHeight di.WithdrawalHeight = height @@ -200,11 +200,11 @@ func (di DelegatorDistInfo) WithdrawRewards(g Global, vi ValidatorDistInfo, Commission is calculated each time rewards enter into the validator. ``` -func (vi ValidatorDistInfo) WithdrawCommission(g Global, height int64, +func (vi ValidatorDistInfo) WithdrawCommission(g FeePool, height int64, totalBonded, vdTokens, commissionRate Dec) ( - vi ValidatorDistInfo, g Global, withdrawn DecCoins) + vi ValidatorDistInfo, g FeePool, withdrawn DecCoins) - g = vi.TakeGlobalRewards(g, height, totalBonded, vdTokens, commissionRate) + g = vi.TakeFeePoolRewards(g, height, totalBonded, vdTokens, commissionRate) withdrawalTokens := vi.PoolCommission vi.PoolCommission = 0 diff --git a/x/distribution/keeper/allocation.go b/x/distribution/keeper/allocation.go index 597be2adb..9f54b700e 100644 --- a/x/distribution/keeper/allocation.go +++ b/x/distribution/keeper/allocation.go @@ -3,28 +3,27 @@ package keeper import sdk "github.com/cosmos/cosmos-sdk/types" // XXX TODO -func (k Keeper) AllocateFees(ctx sdk.Context, feesCollected sdk.Coins, proposerAddr sdk.ConsAddrs, +func (k Keeper) AllocateFees(ctx sdk.Context, feesCollected sdk.Coins, proposerAddr sdk.ConsAddress, sumPowerPrecommitValidators, totalBondedTokens, communityTax, proposerCommissionRate sdk.Dec) { feePool := k.GetFeePool() - validator := k.stakeKeeper.GetValidatorFromConsAddr(ctx, - proposerOpAddr := Stake.GetValidator - proposer := k.GetFeeDistribution(ctx, proposerOpAddr) + proserValidator := k.stakeKeeper.GetValidatorFromConsAddr(ctx, proposerAddr) + proposer := k.GetFeeDistribution(ctx, proserValidator.OperatorAddr) - feesCollectedDec = MakeDecCoins(feesCollected) - proposerReward = feesCollectedDec.Mul(sdk.NewDecWithPrec(1, 2) + sdk.NewDecWithPrec(1, 2).Mul(sumPowerPrecommitValidators)/totalBondedTokens) + feesCollectedDec := NewDecCoins(feesCollected) + proposerMultiplier := sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(4, 2).Mul( + sumPowerPrecommitValidators).Div(totalBondedTokens)) + proposerReward := feesCollectedDec.Mul(proposerMultiplier) - commission = proposerReward * proposerCommissionRate - proposer.PoolCommission += commission - proposer.Pool += proposerReward - commission + commission := proposerReward.Mul(proposerCommissionRate) + proposer.PoolCommission = proposer.PoolCommission.Add(commission) + proposer.Pool = proposer.Pool.Add(proposerReward.Sub(commission)) - communityFunding = feesCollectedDec * communityTax - feePool.CommunityFund += communityFunding + communityFunding := feesCollectedDec.Mul(communityTax) + feePool.CommunityFund = feePool.CommunityFund.Add(communityFunding) poolReceived = feesCollectedDec - proposerReward - communityFunding - feePool.Pool += poolReceived - feePool.EverReceivedPool += poolReceived - feePool.LastReceivedPool = poolReceived + feePool.Pool = feePool.Pool.Add(poolReceived) SetValidatorDistribution(proposer) SetFeePool(feePool) diff --git a/x/distribution/keeper/keeper.go b/x/distribution/keeper/keeper.go index c0bf48cea..741e3aa9a 100644 --- a/x/distribution/keeper/keeper.go +++ b/x/distribution/keeper/keeper.go @@ -32,7 +32,7 @@ func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck types.CoinKeeper, //______________________________________________________________________ // get the global fee pool distribution info -func (k Keeper) GetFeePool(ctx sdk.Context) (feePool types.Global) { +func (k Keeper) GetFeePool(ctx sdk.Context) (feePool types.FeePool) { store := ctx.KVStore(k.storeKey) b := store.Get(GlobalKey) @@ -45,7 +45,7 @@ func (k Keeper) GetFeePool(ctx sdk.Context) (feePool types.Global) { } // set the global fee pool distribution info -func (k Keeper) SetFeePool(ctx sdk.Context, feePool types.Global) { +func (k Keeper) SetFeePool(ctx sdk.Context, feePool types.FeePool) { store := ctx.KVStore(k.storeKey) b := k.cdc.MustMarshalBinary(feePool) store.Set(GlobalKey, b) diff --git a/x/distribution/types/dec_coin.go b/x/distribution/types/dec_coin.go new file mode 100644 index 000000000..1bc803530 --- /dev/null +++ b/x/distribution/types/dec_coin.go @@ -0,0 +1,27 @@ +package types + +import sdk "github.com/cosmos/cosmos-sdk/types" + +// coins with decimal +type DecCoins []DecCoin + +// Coins which can have additional decimal points +type DecCoin struct { + Amount sdk.Dec `json:"amount"` + Denom string `json:"denom"` +} + +func NewDecCoin(coin sdk.Coin) DecCoin { + return DecCoins{ + Amount: sdk.NewDec(coin.Amount), + Denom: coin.Denom, + } +} + +func NewDecCoins(coins sdk.Coins) DecCoins { + + dcs := make(DecCoins, len(coins)) + for i, coin := range coins { + dcs[i] = NewDecCoin(coin) + } +} diff --git a/x/distribution/types/fee_pool.go b/x/distribution/types/fee_pool.go index 23e158488..1058db77c 100644 --- a/x/distribution/types/fee_pool.go +++ b/x/distribution/types/fee_pool.go @@ -2,15 +2,6 @@ package types import sdk "github.com/cosmos/cosmos-sdk/types" -// coins with decimal -type DecCoins []DecCoin - -// Coins which can have additional decimal points -type DecCoin struct { - Amount sdk.Dec `json:"amount"` - Denom string `json:"denom"` -} - // total accumulation tracker type TotalAccum struct { UpdateHeight int64 `json:"update_height"`