2019-12-17 03:44:44 -08:00
|
|
|
<!--
|
2019-12-11 09:35:27 -08:00
|
|
|
order: 4
|
2019-12-17 03:44:44 -08:00
|
|
|
-->
|
2019-12-11 09:35:27 -08:00
|
|
|
|
2019-01-21 16:52:03 -08:00
|
|
|
# Messages
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-09-18 20:30:00 -07:00
|
|
|
## MsgWithdrawDelegationRewardsAll
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-08-15 20:33:26 -07:00
|
|
|
When a delegator wishes to withdraw their rewards it must send
|
2018-09-18 20:30:00 -07:00
|
|
|
`MsgWithdrawDelegationRewardsAll`. Note that parts of this transaction logic are also
|
2018-08-08 03:10:21 -07:00
|
|
|
triggered each with any change in individual delegations, such as an unbond,
|
|
|
|
redelegation, or delegation of additional tokens to a specific validator.
|
|
|
|
|
2019-07-01 09:47:55 -07:00
|
|
|
```go
|
2018-09-18 20:30:00 -07:00
|
|
|
type MsgWithdrawDelegationRewardsAll struct {
|
|
|
|
DelegatorAddr sdk.AccAddress
|
2018-08-08 03:10:21 -07:00
|
|
|
}
|
|
|
|
|
2018-09-03 12:49:36 -07:00
|
|
|
func WithdrawDelegationRewardsAll(delegatorAddr, withdrawAddr sdk.AccAddress)
|
2018-08-15 20:33:26 -07:00
|
|
|
height = GetHeight()
|
2018-09-03 12:49:36 -07:00
|
|
|
withdraw = GetDelegatorRewardsAll(delegatorAddr, height)
|
2019-07-01 09:47:55 -07:00
|
|
|
SendCoins(distributionModuleAcc, withdrawAddr, withdraw.TruncateDecimal())
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-09-03 12:49:36 -07:00
|
|
|
func GetDelegatorRewardsAll(delegatorAddr sdk.AccAddress, height int64) DecCoins
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-08-15 20:33:26 -07:00
|
|
|
// get all distribution scenarios
|
2018-08-08 03:10:21 -07:00
|
|
|
delegations = GetDelegations(delegatorAddr)
|
|
|
|
|
2018-08-15 20:33:26 -07:00
|
|
|
// collect all entitled rewards
|
|
|
|
withdraw = 0
|
2019-01-11 12:08:01 -08:00
|
|
|
pool = staking.GetPool()
|
2018-09-05 16:15:15 -07:00
|
|
|
feePool = GetFeePool()
|
2018-08-08 03:10:21 -07:00
|
|
|
for delegation = range delegations
|
2018-08-16 13:41:32 -07:00
|
|
|
delInfo = GetDelegationDistInfo(delegation.DelegatorAddr,
|
2018-08-08 03:10:21 -07:00
|
|
|
delegation.ValidatorAddr)
|
2018-08-16 13:41:32 -07:00
|
|
|
valInfo = GetValidatorDistInfo(delegation.ValidatorAddr)
|
2018-08-08 03:10:21 -07:00
|
|
|
validator = GetValidator(delegation.ValidatorAddr)
|
|
|
|
|
2018-09-05 16:15:15 -07:00
|
|
|
feePool, diWithdraw = delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens,
|
2018-08-15 20:33:26 -07:00
|
|
|
validator.Tokens, validator.DelegatorShares, validator.Commission)
|
2018-08-16 13:41:32 -07:00
|
|
|
withdraw += diWithdraw
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-09-05 16:15:15 -07:00
|
|
|
SetFeePool(feePool)
|
2018-08-15 20:33:26 -07:00
|
|
|
return withdraw
|
2018-08-08 03:10:21 -07:00
|
|
|
```
|
|
|
|
|
2018-09-18 20:30:00 -07:00
|
|
|
## MsgWithdrawDelegationReward
|
2018-08-23 00:19:21 -07:00
|
|
|
|
|
|
|
under special circumstances a delegator may wish to withdraw rewards from only
|
|
|
|
a single validator.
|
|
|
|
|
2019-07-01 09:47:55 -07:00
|
|
|
```go
|
2018-09-18 20:30:00 -07:00
|
|
|
type MsgWithdrawDelegationReward struct {
|
|
|
|
DelegatorAddr sdk.AccAddress
|
|
|
|
ValidatorAddr sdk.ValAddress
|
2018-08-23 00:19:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func WithdrawDelegationReward(delegatorAddr, validatorAddr, withdrawAddr sdk.AccAddress)
|
|
|
|
height = GetHeight()
|
|
|
|
|
|
|
|
// get all distribution scenarios
|
2019-01-11 12:08:01 -08:00
|
|
|
pool = staking.GetPool()
|
2018-09-05 16:15:15 -07:00
|
|
|
feePool = GetFeePool()
|
2018-08-23 00:19:21 -07:00
|
|
|
delInfo = GetDelegationDistInfo(delegatorAddr,
|
|
|
|
validatorAddr)
|
|
|
|
valInfo = GetValidatorDistInfo(validatorAddr)
|
|
|
|
validator = GetValidator(validatorAddr)
|
|
|
|
|
2018-09-05 16:15:15 -07:00
|
|
|
feePool, withdraw = delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens,
|
2018-08-23 00:19:21 -07:00
|
|
|
validator.Tokens, validator.DelegatorShares, validator.Commission)
|
|
|
|
|
2018-09-05 16:15:15 -07:00
|
|
|
SetFeePool(feePool)
|
2019-07-01 09:47:55 -07:00
|
|
|
SendCoins(distributionModuleAcc, withdrawAddr, withdraw.TruncateDecimal())
|
2018-08-23 00:19:21 -07:00
|
|
|
```
|
|
|
|
|
|
|
|
|
2018-09-18 20:30:00 -07:00
|
|
|
## MsgWithdrawValidatorRewardsAll
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-08-15 20:33:26 -07:00
|
|
|
When a validator wishes to withdraw their rewards it must send
|
2018-09-18 20:30:00 -07:00
|
|
|
`MsgWithdrawValidatorRewardsAll`. Note that parts of this transaction logic are also
|
2018-08-08 03:10:21 -07:00
|
|
|
triggered each with any change in individual delegations, such as an unbond,
|
|
|
|
redelegation, or delegation of additional tokens to a specific validator. This
|
2018-08-15 20:33:26 -07:00
|
|
|
transaction withdraws the validators commission fee, as well as any rewards
|
2019-07-01 09:47:55 -07:00
|
|
|
earning on their self-delegation.
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2019-07-01 09:47:55 -07:00
|
|
|
```go
|
2018-09-18 20:30:00 -07:00
|
|
|
type MsgWithdrawValidatorRewardsAll struct {
|
|
|
|
OperatorAddr sdk.ValAddress // validator address to withdraw from
|
2018-08-08 03:10:21 -07:00
|
|
|
}
|
|
|
|
|
2018-09-03 12:49:36 -07:00
|
|
|
func WithdrawValidatorRewardsAll(operatorAddr, withdrawAddr sdk.AccAddress)
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-08-15 20:33:26 -07:00
|
|
|
height = GetHeight()
|
2018-09-05 16:15:15 -07:00
|
|
|
feePool = GetFeePool()
|
2018-08-08 03:10:21 -07:00
|
|
|
pool = GetPool()
|
2018-08-16 13:41:32 -07:00
|
|
|
ValInfo = GetValidatorDistInfo(delegation.ValidatorAddr)
|
2018-08-08 03:10:21 -07:00
|
|
|
validator = GetValidator(delegation.ValidatorAddr)
|
|
|
|
|
2018-08-15 20:33:26 -07:00
|
|
|
// withdraw self-delegation
|
2018-09-03 12:49:36 -07:00
|
|
|
withdraw = GetDelegatorRewardsAll(validator.OperatorAddr, height)
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-08-15 20:33:26 -07:00
|
|
|
// withdrawal validator commission rewards
|
2018-09-05 16:15:15 -07:00
|
|
|
feePool, commission = valInfo.WithdrawCommission(feePool, valInfo, height, pool.BondedTokens,
|
2018-08-23 00:19:21 -07:00
|
|
|
validator.Tokens, validator.Commission)
|
2018-08-15 20:33:26 -07:00
|
|
|
withdraw += commission
|
2018-09-05 16:15:15 -07:00
|
|
|
SetFeePool(feePool)
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2019-07-01 09:47:55 -07:00
|
|
|
SendCoins(distributionModuleAcc, withdrawAddr, withdraw.TruncateDecimal())
|
2018-08-08 03:10:21 -07:00
|
|
|
```
|
2019-07-01 09:47:55 -07:00
|
|
|
|
2018-08-14 20:33:40 -07:00
|
|
|
## Common calculations
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-08-08 21:34:19 -07:00
|
|
|
### Update total validator accum
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-08-08 21:34:19 -07:00
|
|
|
The total amount of validator accum must be calculated in order to determine
|
2018-08-14 10:45:13 -07:00
|
|
|
the amount of pool tokens which a validator is entitled to at a particular
|
|
|
|
block. The accum is always additive to the existing accum. This term is to be
|
2018-08-20 08:50:13 -07:00
|
|
|
updated each time rewards are withdrawn from the system.
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2019-07-01 09:47:55 -07:00
|
|
|
```go
|
2018-09-05 16:15:15 -07:00
|
|
|
func (g FeePool) UpdateTotalValAccum(height int64, totalBondedTokens Dec) FeePool
|
2018-08-14 10:45:13 -07:00
|
|
|
blocks = height - g.TotalValAccumUpdateHeight
|
|
|
|
g.TotalValAccum += totalDelShares * blocks
|
2018-08-15 17:03:39 -07:00
|
|
|
g.TotalValAccumUpdateHeight = height
|
2018-09-03 12:49:36 -07:00
|
|
|
return g
|
2018-08-14 10:45:13 -07:00
|
|
|
```
|
|
|
|
|
2018-08-14 20:33:40 -07:00
|
|
|
### Update validator's accums
|
2018-08-08 21:34:19 -07:00
|
|
|
|
2018-08-14 10:45:13 -07:00
|
|
|
The total amount of delegator accum must be updated in order to determine the
|
|
|
|
amount of pool tokens which each delegator is entitled to, relative to the
|
|
|
|
other delegators for that validator. The accum is always additive to
|
|
|
|
the existing accum. This term is to be updated each time a
|
|
|
|
withdrawal is made from a validator.
|
2018-08-08 21:34:19 -07:00
|
|
|
|
2019-07-01 09:47:55 -07:00
|
|
|
``` go
|
2018-09-03 12:49:36 -07:00
|
|
|
func (vi ValidatorDistInfo) UpdateTotalDelAccum(height int64, totalDelShares Dec) ValidatorDistInfo
|
2018-08-16 13:41:32 -07:00
|
|
|
blocks = height - vi.TotalDelAccumUpdateHeight
|
|
|
|
vi.TotalDelAccum += totalDelShares * blocks
|
|
|
|
vi.TotalDelAccumUpdateHeight = height
|
2018-09-03 12:49:36 -07:00
|
|
|
return vi
|
2018-08-08 21:34:19 -07:00
|
|
|
```
|
|
|
|
|
2018-09-05 16:15:15 -07:00
|
|
|
### FeePool pool to validator pool
|
2018-08-08 21:34:19 -07:00
|
|
|
|
2018-08-23 00:19:21 -07:00
|
|
|
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
|
|
|
|
from the passive global pool to their own pool. It is at this point that the
|
|
|
|
commission is withdrawn
|
2018-08-08 21:34:19 -07:00
|
|
|
|
2019-07-01 09:47:55 -07:00
|
|
|
```go
|
2018-09-05 16:15:15 -07:00
|
|
|
func (vi ValidatorDistInfo) TakeFeePoolRewards(g FeePool, height int64, totalBonded, vdTokens, commissionRate Dec) (
|
|
|
|
vi ValidatorDistInfo, g FeePool)
|
2018-09-03 12:49:36 -07:00
|
|
|
|
2018-08-14 10:45:13 -07:00
|
|
|
g.UpdateTotalValAccum(height, totalBondedShares)
|
2018-08-14 20:33:40 -07:00
|
|
|
|
|
|
|
// update the validators pool
|
2018-09-05 16:15:15 -07:00
|
|
|
blocks = height - vi.FeePoolWithdrawalHeight
|
|
|
|
vi.FeePoolWithdrawalHeight = height
|
2018-08-14 20:33:40 -07:00
|
|
|
accum = blocks * vdTokens
|
|
|
|
withdrawalTokens := g.Pool * accum / g.TotalValAccum
|
2018-08-23 00:19:21 -07:00
|
|
|
commission := withdrawalTokens * commissionRate
|
2018-08-14 20:33:40 -07:00
|
|
|
|
2018-08-15 01:12:44 -07:00
|
|
|
g.TotalValAccum -= accumm
|
2018-08-23 00:19:21 -07:00
|
|
|
vi.PoolCommission += commission
|
|
|
|
vi.PoolCommissionFree += withdrawalTokens - commission
|
2018-08-14 20:33:40 -07:00
|
|
|
g.Pool -= withdrawalTokens
|
|
|
|
|
2018-09-03 12:49:36 -07:00
|
|
|
return vi, g
|
2018-08-08 21:34:19 -07:00
|
|
|
```
|
|
|
|
|
|
|
|
|
2018-08-20 08:50:13 -07:00
|
|
|
### Delegation reward withdrawal
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-08-23 00:19:21 -07:00
|
|
|
For delegations (including validator's self-delegation) all rewards from reward
|
|
|
|
pool have already had the validator's commission taken away.
|
2018-08-08 21:34:19 -07:00
|
|
|
|
2019-07-01 09:47:55 -07:00
|
|
|
```go
|
2018-10-05 17:32:06 -07:00
|
|
|
func (di DelegationDistInfo) WithdrawRewards(g FeePool, vi ValidatorDistInfo,
|
2018-09-03 12:49:36 -07:00
|
|
|
height int64, totalBonded, vdTokens, totalDelShares, commissionRate Dec) (
|
2018-10-05 17:32:06 -07:00
|
|
|
di DelegationDistInfo, g FeePool, withdrawn DecCoins)
|
2018-08-14 20:33:40 -07:00
|
|
|
|
2018-08-16 13:41:32 -07:00
|
|
|
vi.UpdateTotalDelAccum(height, totalDelShares)
|
2018-09-05 16:15:15 -07:00
|
|
|
g = vi.TakeFeePoolRewards(g, height, totalBonded, vdTokens, commissionRate)
|
2018-08-14 20:33:40 -07:00
|
|
|
|
2018-08-16 13:41:32 -07:00
|
|
|
blocks = height - di.WithdrawalHeight
|
|
|
|
di.WithdrawalHeight = height
|
2018-08-23 00:19:21 -07:00
|
|
|
accum = delegatorShares * blocks
|
2018-08-15 01:12:44 -07:00
|
|
|
|
2018-08-16 13:41:32 -07:00
|
|
|
withdrawalTokens := vi.Pool * accum / vi.TotalDelAccum
|
|
|
|
vi.TotalDelAccum -= accum
|
2018-08-15 17:03:39 -07:00
|
|
|
|
2018-08-16 13:41:32 -07:00
|
|
|
vi.Pool -= withdrawalTokens
|
|
|
|
vi.TotalDelAccum -= accum
|
2018-09-03 12:49:36 -07:00
|
|
|
return di, g, withdrawalTokens
|
2018-08-14 20:33:40 -07:00
|
|
|
|
2018-08-08 03:10:21 -07:00
|
|
|
```
|
|
|
|
|
2018-08-20 08:50:13 -07:00
|
|
|
### Validator commission withdrawal
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2018-08-23 00:19:21 -07:00
|
|
|
Commission is calculated each time rewards enter into the validator.
|
2018-08-08 03:10:21 -07:00
|
|
|
|
2019-07-01 09:47:55 -07:00
|
|
|
```go
|
2018-09-05 16:15:15 -07:00
|
|
|
func (vi ValidatorDistInfo) WithdrawCommission(g FeePool, height int64,
|
2018-09-03 12:49:36 -07:00
|
|
|
totalBonded, vdTokens, commissionRate Dec) (
|
2018-09-05 16:15:15 -07:00
|
|
|
vi ValidatorDistInfo, g FeePool, withdrawn DecCoins)
|
2018-08-15 01:12:44 -07:00
|
|
|
|
2018-09-05 16:15:15 -07:00
|
|
|
g = vi.TakeFeePoolRewards(g, height, totalBonded, vdTokens, commissionRate)
|
2018-08-15 01:12:44 -07:00
|
|
|
|
2018-08-23 00:19:21 -07:00
|
|
|
withdrawalTokens := vi.PoolCommission
|
|
|
|
vi.PoolCommission = 0
|
2018-08-15 01:12:44 -07:00
|
|
|
|
2018-09-03 12:49:36 -07:00
|
|
|
return vi, g, withdrawalTokens
|
2018-08-08 03:10:21 -07:00
|
|
|
```
|