From 2d613cefe7da94d9e9bdd30314e914c1447c499f Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 8 Aug 2018 14:24:38 -0400 Subject: [PATCH] move lamborghini distribution to subfolder --- .../WIP-lamborghini-distribution/README.md | 2 + .../end_block.md | 0 .../example_sheet/distribution.xlsx | Bin .../future_improvements.md | 0 .../WIP-lamborghini-distribution/overview.md | 54 ++++++++++ .../WIP-lamborghini-distribution/state.md | 100 ++++++++++++++++++ .../transactions.md | 0 .../WIP-lamborghini-distribution}/triggers.md | 0 docs/spec/distribution/overview.md | 54 ++++++---- docs/spec/distribution/state.md | 56 +++------- docs/spec/simple-distribution/overview.md | 64 ----------- docs/spec/simple-distribution/state.md | 68 ------------ 12 files changed, 200 insertions(+), 198 deletions(-) create mode 100644 docs/spec/distribution/WIP-lamborghini-distribution/README.md rename docs/spec/{simple-distribution => distribution/WIP-lamborghini-distribution}/end_block.md (100%) rename docs/spec/distribution/{ => WIP-lamborghini-distribution}/example_sheet/distribution.xlsx (100%) rename docs/spec/{simple-distribution => distribution/WIP-lamborghini-distribution}/future_improvements.md (100%) create mode 100644 docs/spec/distribution/WIP-lamborghini-distribution/overview.md create mode 100644 docs/spec/distribution/WIP-lamborghini-distribution/state.md rename docs/spec/{simple-distribution => distribution/WIP-lamborghini-distribution}/transactions.md (100%) rename docs/spec/{simple-distribution => distribution/WIP-lamborghini-distribution}/triggers.md (100%) delete mode 100644 docs/spec/simple-distribution/overview.md delete mode 100644 docs/spec/simple-distribution/state.md diff --git a/docs/spec/distribution/WIP-lamborghini-distribution/README.md b/docs/spec/distribution/WIP-lamborghini-distribution/README.md new file mode 100644 index 000000000..c09042f7f --- /dev/null +++ b/docs/spec/distribution/WIP-lamborghini-distribution/README.md @@ -0,0 +1,2 @@ +Please note that this folder is a WIP specification for an advanced fee distribution +mechanism which is not set to be implemented. diff --git a/docs/spec/simple-distribution/end_block.md b/docs/spec/distribution/WIP-lamborghini-distribution/end_block.md similarity index 100% rename from docs/spec/simple-distribution/end_block.md rename to docs/spec/distribution/WIP-lamborghini-distribution/end_block.md diff --git a/docs/spec/distribution/example_sheet/distribution.xlsx b/docs/spec/distribution/WIP-lamborghini-distribution/example_sheet/distribution.xlsx similarity index 100% rename from docs/spec/distribution/example_sheet/distribution.xlsx rename to docs/spec/distribution/WIP-lamborghini-distribution/example_sheet/distribution.xlsx diff --git a/docs/spec/simple-distribution/future_improvements.md b/docs/spec/distribution/WIP-lamborghini-distribution/future_improvements.md similarity index 100% rename from docs/spec/simple-distribution/future_improvements.md rename to docs/spec/distribution/WIP-lamborghini-distribution/future_improvements.md diff --git a/docs/spec/distribution/WIP-lamborghini-distribution/overview.md b/docs/spec/distribution/WIP-lamborghini-distribution/overview.md new file mode 100644 index 000000000..5e28e8b3b --- /dev/null +++ b/docs/spec/distribution/WIP-lamborghini-distribution/overview.md @@ -0,0 +1,54 @@ +# Distribution + +## Overview + +Collected fees are pooled globally and divided out passively to validators and +delegators. Each validator has the opportunity to charge commission to the +delegators on the fees collected on behalf of the delegators by the validators. +Fees are paid directly into a global fee pool, and validator proposer-reward +pool. Due to the nature of passive accounting whenever changes to parameters +which affect the rate of fee distribution occurs, withdrawal of fees must also +occur when: + + - withdrawing one must withdrawal the maximum amount they are entitled + too, leaving nothing in the pool, + - bonding, unbonding, or re-delegating tokens to an existing account a + full withdrawal of the fees must occur (as the rules for lazy accounting + change), + - a validator chooses to change the commission on fees, all accumulated + commission fees must be simultaneously withdrawn. + +The above scenarios are covered in `triggers.md`. + +The distribution mechanism outlines herein is used to lazily distribute the +following between validators and associated delegators: + - multi-token fees to be socially distributed, + - proposer reward pool, + - inflated atom provisions, and + - validator commission on all rewards earned by their delegators stake + +Fees are pooled within a global pool, as well as validator specific +proposer-reward pools. The mechanisms used allow for validators and delegators +to independently and lazily withdrawn their rewards. As a part of the lazy +computations adjustment factors must be maintained for each validator and +delegator to determine the true proportion of fees in each pool which they are +entitled too. Adjustment factors are updated every time a validator or +delegator's voting power changes. Validators and delegators must withdraw all +fees they are entitled too before they can change their portion of bonded +Atoms. + +## Affect on Staking + + +Charging commission on Atom provisions while also allowing for Atom-provisions +to be auto-bonded (distributed directly to the validators bonded stake) is +problematic within DPoS. Fundamentally these two mechnisms are mutually +exclusive. If there are atoms commissions and auto-bonding Atoms, the portion +of Atoms the fee distribution calculation would become very large as the Atom +portion for each delegator would change each block making a withdrawal of fees +for a delegator require a calculation for every single block since the last +withdrawal. In conclusion we can only have atom commission and unbonded atoms +provisions, or bonded atom provisions with no Atom commission, and we elect to +implement the former. Stakeholders wishing to rebond their provisions may elect +to set up a script to periodically withdraw and rebond fees. + diff --git a/docs/spec/distribution/WIP-lamborghini-distribution/state.md b/docs/spec/distribution/WIP-lamborghini-distribution/state.md new file mode 100644 index 000000000..7865c085e --- /dev/null +++ b/docs/spec/distribution/WIP-lamborghini-distribution/state.md @@ -0,0 +1,100 @@ +## State + +### Global + +All globally tracked parameters for distribution are stored within +`Global`. 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 +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)` + +```golang +// coins with decimal +type DecCoins []DecCoin + +type DecCoin struct { + Amount sdk.Dec + Denom string +} + +type Global struct { + PrevBondedTokens sdk.Dec // bonded token amount for the global pool on the previous block + Adjustment sdk.Dec // global adjustment factor for lazy calculations + Pool DecCoins // funds for all validators which have yet to be withdrawn + PrevReceivedPool DecCoins // funds added to the pool on the previous block + EverReceivedPool DecCoins // total funds ever added to the pool + CommunityFund DecCoins // pool for community funds yet to be spent +} +``` + +### Validator Distribution + +Validator distribution information for the relevant validator is updated each time: + 1. delegation amount to a validator are updated, + 2. a validator successfully proposes a block and receives a reward, + 3. any delegator withdraws from a validator, or + 4. the validator withdraws it's commission. + + - ValidatorDistribution: `0x02 | ValOwnerAddr -> amino(validatorDistribution)` + +```golang +type ValidatorDistribution struct { + CommissionWithdrawalHeight int64 // last time this validator withdrew commission + Adjustment sdk.Dec // global pool adjustment factor + ProposerAdjustment DecCoins // proposer pool adjustment factor + ProposerPool DecCoins // reward pool collected from being the proposer + EverReceivedProposerReward DecCoins // all rewards ever collected from being the proposer + PrevReceivedProposerReward DecCoins // previous rewards collected from being the proposer + PrevBondedTokens sdk.Dec // bonded token amount on the previous block + PrevDelegatorShares sdk.Dec // amount of delegator shares for the validator on the previous block +} +``` + +### Delegation Distribution + +Each delegation holds multiple adjustment factors to specify its entitlement to +the rewards from a validator. `AdjustmentPool` is used to passively calculate +each bonds entitled fees from the `RewardPool`. `AdjustmentPool` is used to +passively calculate each bonds entitled fees from +`ValidatorDistribution.ProposerRewardPool` + + - DelegatorDistribution: ` 0x02 | DelegatorAddr | ValOwnerAddr -> amino(delegatorDist)` + +```golang +type DelegatorDist struct { + WithdrawalHeight int64 // last time this delegation withdrew rewards + Adjustment sdk.Dec // fee provisioning adjustment factor + AdjustmentProposer DecCoins // proposers pool adjustment factor + PrevTokens sdk.Dec // bonded tokens held by the delegation on the previous block + PrevShares sdk.Dec // delegator shares held by the delegation on the previous block +} +``` + +### Power Change + +Every instance that the voting power changes, information about the state of +the validator set during the change must be recorded as a `PowerChange` for +other validators to run through. Each power change is indexed by its block +height. + + - PowerChange: `0x03 | amino(Height) -> amino(validatorDist)` + +```golang +type PowerChange struct { + Height int64 // block height at change + ValidatorBondedTokens sdk.Dec // following used to create distribution scenarios + ValidatorDelegatorShares sdk.Dec + ValidatorDelegatorShareExRate sdk.Dec + ValidatorCommission sdk.Dec + PoolBondedTokens sdk.Dec + Global Global + ValDistr ValidatorDistribution + DelegationShares sdk.Dec + DelDistr DelegatorDistribution +} +``` diff --git a/docs/spec/simple-distribution/transactions.md b/docs/spec/distribution/WIP-lamborghini-distribution/transactions.md similarity index 100% rename from docs/spec/simple-distribution/transactions.md rename to docs/spec/distribution/WIP-lamborghini-distribution/transactions.md diff --git a/docs/spec/simple-distribution/triggers.md b/docs/spec/distribution/WIP-lamborghini-distribution/triggers.md similarity index 100% rename from docs/spec/simple-distribution/triggers.md rename to docs/spec/distribution/WIP-lamborghini-distribution/triggers.md diff --git a/docs/spec/distribution/overview.md b/docs/spec/distribution/overview.md index 5e28e8b3b..62cec2e76 100644 --- a/docs/spec/distribution/overview.md +++ b/docs/spec/distribution/overview.md @@ -2,26 +2,31 @@ ## Overview -Collected fees are pooled globally and divided out passively to validators and -delegators. Each validator has the opportunity to charge commission to the -delegators on the fees collected on behalf of the delegators by the validators. -Fees are paid directly into a global fee pool, and validator proposer-reward -pool. Due to the nature of passive accounting whenever changes to parameters -which affect the rate of fee distribution occurs, withdrawal of fees must also -occur when: +This _simple_ distribution mechanism describes a functional way to passively +distribute rewards between validator and delegators. Note that this mechanism does +not distribute funds in as precisely as active reward distribution and will therefor +be upgraded in the future. + +The mechanism operates as follows. Collected rewards are pooled globally and +divided out passively to validators and delegators. Each validator has the +opportunity to charge commission to the delegators on the rewards collected on +behalf of the delegators by the validators. Fees are paid directly into a +global reward pool, and validator proposer-reward pool. Due to the nature of +passive accounting whenever changes to parameters which affect the rate of reward +distribution occurs, withdrawal of rewards must also occur when: - withdrawing one must withdrawal the maximum amount they are entitled too, leaving nothing in the pool, - bonding, unbonding, or re-delegating tokens to an existing account a - full withdrawal of the fees must occur (as the rules for lazy accounting + full withdrawal of the rewards must occur (as the rules for lazy accounting change), - - a validator chooses to change the commission on fees, all accumulated - commission fees must be simultaneously withdrawn. + - a validator chooses to change the commission on rewards, all accumulated + commission rewards must be simultaneously withdrawn. The above scenarios are covered in `triggers.md`. The distribution mechanism outlines herein is used to lazily distribute the -following between validators and associated delegators: +following rewards between validators and associated delegators: - multi-token fees to be socially distributed, - proposer reward pool, - inflated atom provisions, and @@ -29,26 +34,31 @@ following between validators and associated delegators: Fees are pooled within a global pool, as well as validator specific proposer-reward pools. The mechanisms used allow for validators and delegators -to independently and lazily withdrawn their rewards. As a part of the lazy -computations adjustment factors must be maintained for each validator and -delegator to determine the true proportion of fees in each pool which they are -entitled too. Adjustment factors are updated every time a validator or -delegator's voting power changes. Validators and delegators must withdraw all -fees they are entitled too before they can change their portion of bonded -Atoms. +to independently and lazily withdrawn their rewards. + +Within this spec + +As a part of the lazy computations, each validator and delegator holds an +accumulation term which is used to estimate what their approximate fair portion +of tokens held in the global pool is owed to them. This approximation of owed +rewards would be equivalent to the active distribution under the situation that +there was a constant flow of incoming reward tokens every block. Because this +is not the case, the approximation of owed rewards will deviate from the active +distribution based on fluctuations of incoming reward tokens as well as timing +of reward withdrawal by other delegators and validators from the reward pool. + ## Affect on Staking - Charging commission on Atom provisions while also allowing for Atom-provisions to be auto-bonded (distributed directly to the validators bonded stake) is problematic within DPoS. Fundamentally these two mechnisms are mutually exclusive. If there are atoms commissions and auto-bonding Atoms, the portion -of Atoms the fee distribution calculation would become very large as the Atom -portion for each delegator would change each block making a withdrawal of fees +of Atoms the reward distribution calculation would become very large as the Atom +portion for each delegator would change each block making a withdrawal of rewards for a delegator require a calculation for every single block since the last withdrawal. In conclusion we can only have atom commission and unbonded atoms provisions, or bonded atom provisions with no Atom commission, and we elect to implement the former. Stakeholders wishing to rebond their provisions may elect -to set up a script to periodically withdraw and rebond fees. +to set up a script to periodically withdraw and rebond rewards. diff --git a/docs/spec/distribution/state.md b/docs/spec/distribution/state.md index 7865c085e..757287004 100644 --- a/docs/spec/distribution/state.md +++ b/docs/spec/distribution/state.md @@ -23,11 +23,8 @@ type DecCoin struct { } type Global struct { - PrevBondedTokens sdk.Dec // bonded token amount for the global pool on the previous block - Adjustment sdk.Dec // global adjustment factor for lazy calculations + Accum sdk.Dec // global accumulation factor for lazy calculations Pool DecCoins // funds for all validators which have yet to be withdrawn - PrevReceivedPool DecCoins // funds added to the pool on the previous block - EverReceivedPool DecCoins // total funds ever added to the pool CommunityFund DecCoins // pool for community funds yet to be spent } ``` @@ -44,57 +41,28 @@ Validator distribution information for the relevant validator is updated each ti ```golang type ValidatorDistribution struct { - CommissionWithdrawalHeight int64 // last time this validator withdrew commission - Adjustment sdk.Dec // global pool adjustment factor - ProposerAdjustment DecCoins // proposer pool adjustment factor - ProposerPool DecCoins // reward pool collected from being the proposer - EverReceivedProposerReward DecCoins // all rewards ever collected from being the proposer - PrevReceivedProposerReward DecCoins // previous rewards collected from being the proposer - PrevBondedTokens sdk.Dec // bonded token amount on the previous block - PrevDelegatorShares sdk.Dec // amount of delegator shares for the validator on the previous block + CommissionWithdrawalHeight int64 // last time this validator withdrew commission + Accum sdk.Dec // global pool accumulation factor + ProposerAccum sdk.Dec // proposer pool accumulation factor + ProposerPool DecCoins // reward pool collected from being the proposer } ``` ### Delegation Distribution -Each delegation holds multiple adjustment factors to specify its entitlement to -the rewards from a validator. `AdjustmentPool` is used to passively calculate -each bonds entitled fees from the `RewardPool`. `AdjustmentPool` is used to -passively calculate each bonds entitled fees from +Each delegation holds multiple accumulation factors to specify its entitlement to +the rewards from a validator. `Accum` is used to passively calculate +each bonds entitled rewards from the `RewardPool`. `AccumProposer` is used to +passively calculate each bonds entitled rewards from `ValidatorDistribution.ProposerRewardPool` - DelegatorDistribution: ` 0x02 | DelegatorAddr | ValOwnerAddr -> amino(delegatorDist)` ```golang type DelegatorDist struct { - WithdrawalHeight int64 // last time this delegation withdrew rewards - Adjustment sdk.Dec // fee provisioning adjustment factor - AdjustmentProposer DecCoins // proposers pool adjustment factor - PrevTokens sdk.Dec // bonded tokens held by the delegation on the previous block - PrevShares sdk.Dec // delegator shares held by the delegation on the previous block + WithdrawalHeight int64 // last time this delegation withdrew rewards + Accum sdk.Dec // reward provisioning accumulation factor + AccumProposer sdk.Dec // proposers pool accumulation factor } ``` -### Power Change - -Every instance that the voting power changes, information about the state of -the validator set during the change must be recorded as a `PowerChange` for -other validators to run through. Each power change is indexed by its block -height. - - - PowerChange: `0x03 | amino(Height) -> amino(validatorDist)` - -```golang -type PowerChange struct { - Height int64 // block height at change - ValidatorBondedTokens sdk.Dec // following used to create distribution scenarios - ValidatorDelegatorShares sdk.Dec - ValidatorDelegatorShareExRate sdk.Dec - ValidatorCommission sdk.Dec - PoolBondedTokens sdk.Dec - Global Global - ValDistr ValidatorDistribution - DelegationShares sdk.Dec - DelDistr DelegatorDistribution -} -``` diff --git a/docs/spec/simple-distribution/overview.md b/docs/spec/simple-distribution/overview.md deleted file mode 100644 index 62cec2e76..000000000 --- a/docs/spec/simple-distribution/overview.md +++ /dev/null @@ -1,64 +0,0 @@ -# Distribution - -## Overview - -This _simple_ distribution mechanism describes a functional way to passively -distribute rewards between validator and delegators. Note that this mechanism does -not distribute funds in as precisely as active reward distribution and will therefor -be upgraded in the future. - -The mechanism operates as follows. Collected rewards are pooled globally and -divided out passively to validators and delegators. Each validator has the -opportunity to charge commission to the delegators on the rewards collected on -behalf of the delegators by the validators. Fees are paid directly into a -global reward pool, and validator proposer-reward pool. Due to the nature of -passive accounting whenever changes to parameters which affect the rate of reward -distribution occurs, withdrawal of rewards must also occur when: - - - withdrawing one must withdrawal the maximum amount they are entitled - too, leaving nothing in the pool, - - bonding, unbonding, or re-delegating tokens to an existing account a - full withdrawal of the rewards must occur (as the rules for lazy accounting - change), - - a validator chooses to change the commission on rewards, all accumulated - commission rewards must be simultaneously withdrawn. - -The above scenarios are covered in `triggers.md`. - -The distribution mechanism outlines herein is used to lazily distribute the -following rewards between validators and associated delegators: - - multi-token fees to be socially distributed, - - proposer reward pool, - - inflated atom provisions, and - - validator commission on all rewards earned by their delegators stake - -Fees are pooled within a global pool, as well as validator specific -proposer-reward pools. The mechanisms used allow for validators and delegators -to independently and lazily withdrawn their rewards. - -Within this spec - -As a part of the lazy computations, each validator and delegator holds an -accumulation term which is used to estimate what their approximate fair portion -of tokens held in the global pool is owed to them. This approximation of owed -rewards would be equivalent to the active distribution under the situation that -there was a constant flow of incoming reward tokens every block. Because this -is not the case, the approximation of owed rewards will deviate from the active -distribution based on fluctuations of incoming reward tokens as well as timing -of reward withdrawal by other delegators and validators from the reward pool. - - -## Affect on Staking - -Charging commission on Atom provisions while also allowing for Atom-provisions -to be auto-bonded (distributed directly to the validators bonded stake) is -problematic within DPoS. Fundamentally these two mechnisms are mutually -exclusive. If there are atoms commissions and auto-bonding Atoms, the portion -of Atoms the reward distribution calculation would become very large as the Atom -portion for each delegator would change each block making a withdrawal of rewards -for a delegator require a calculation for every single block since the last -withdrawal. In conclusion we can only have atom commission and unbonded atoms -provisions, or bonded atom provisions with no Atom commission, and we elect to -implement the former. Stakeholders wishing to rebond their provisions may elect -to set up a script to periodically withdraw and rebond rewards. - diff --git a/docs/spec/simple-distribution/state.md b/docs/spec/simple-distribution/state.md deleted file mode 100644 index 757287004..000000000 --- a/docs/spec/simple-distribution/state.md +++ /dev/null @@ -1,68 +0,0 @@ -## State - -### Global - -All globally tracked parameters for distribution are stored within -`Global`. 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 -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)` - -```golang -// coins with decimal -type DecCoins []DecCoin - -type DecCoin struct { - Amount sdk.Dec - Denom string -} - -type Global struct { - Accum sdk.Dec // global accumulation factor for lazy calculations - Pool DecCoins // funds for all validators which have yet to be withdrawn - CommunityFund DecCoins // pool for community funds yet to be spent -} -``` - -### Validator Distribution - -Validator distribution information for the relevant validator is updated each time: - 1. delegation amount to a validator are updated, - 2. a validator successfully proposes a block and receives a reward, - 3. any delegator withdraws from a validator, or - 4. the validator withdraws it's commission. - - - ValidatorDistribution: `0x02 | ValOwnerAddr -> amino(validatorDistribution)` - -```golang -type ValidatorDistribution struct { - CommissionWithdrawalHeight int64 // last time this validator withdrew commission - Accum sdk.Dec // global pool accumulation factor - ProposerAccum sdk.Dec // proposer pool accumulation factor - ProposerPool DecCoins // reward pool collected from being the proposer -} -``` - -### Delegation Distribution - -Each delegation holds multiple accumulation factors to specify its entitlement to -the rewards from a validator. `Accum` is used to passively calculate -each bonds entitled rewards from the `RewardPool`. `AccumProposer` is used to -passively calculate each bonds entitled rewards from -`ValidatorDistribution.ProposerRewardPool` - - - DelegatorDistribution: ` 0x02 | DelegatorAddr | ValOwnerAddr -> amino(delegatorDist)` - -```golang -type DelegatorDist struct { - WithdrawalHeight int64 // last time this delegation withdrew rewards - Accum sdk.Dec // reward provisioning accumulation factor - AccumProposer sdk.Dec // proposers pool accumulation factor -} -``` -