cosmos-sdk/docs/spec/distribution/transactions.md

184 lines
6.3 KiB
Markdown
Raw Normal View History

# Transactions
## TxWithdrawDelegation
2018-08-15 20:33:26 -07:00
When a delegator wishes to withdraw their rewards it must send
`TxWithdrawDelegation`. Note that parts of this transaction logic are also
triggered each with any change in individual delegations, such as an unbond,
redelegation, or delegation of additional tokens to a specific validator.
```golang
type TxWithdrawDelegation struct {
delegatorAddr sdk.AccAddress
withdrawAddr sdk.AccAddress // address to make the withdrawal to
}
2018-08-15 20:33:26 -07:00
func WithdrawFromDelegator(delegatorAddr, withdrawAddr sdk.AccAddress)
height = GetHeight()
withdraw = GetDelegatorAllWithdraws(delegatorAddr, height)
AddCoins(withdrawAddr, totalEntitlment.TruncateDecimal())
2018-08-15 20:33:26 -07:00
func GetDelegatorAllWithdraws(delegatorAddr sdk.AccAddress, height int64) DecCoins
2018-08-15 20:33:26 -07:00
// get all distribution scenarios
delegations = GetDelegations(delegatorAddr)
2018-08-15 20:33:26 -07:00
// collect all entitled rewards
withdraw = 0
pool = stake.GetPool()
global = GetGlobal()
for delegation = range delegations
2018-08-15 20:33:26 -07:00
delDistr = GetDelegationDistribution(delegation.DelegatorAddr,
delegation.ValidatorAddr)
2018-08-15 20:33:26 -07:00
valDistr = GetValidatorDistribution(delegation.ValidatorAddr)
validator = GetValidator(delegation.ValidatorAddr)
2018-08-15 20:33:26 -07:00
global, ddWithdraw = delDistr.WithdrawRewards(global, valDistr, height, pool.BondedTokens,
validator.Tokens, validator.DelegatorShares, validator.Commission)
withdraw += ddWithdraw
2018-08-15 20:33:26 -07:00
SetGlobal(global)
return withdraw
```
## TxWithdrawValidator
2018-08-15 20:33:26 -07:00
When a validator wishes to withdraw their rewards it must send
`TxWithdrawDelegation`. Note that parts of this transaction logic is also
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
earning on their self-delegation.
2018-08-08 21:34:19 -07:00
```
type TxWithdrawValidator struct {
2018-08-15 20:33:26 -07:00
operatorAddr sdk.AccAddress // validator address to withdraw from
withdrawAddr sdk.AccAddress // address to make the withdrawal to
}
2018-08-15 20:33:26 -07:00
func WithdrawFromValidator(operatorAddr, withdrawAddr sdk.AccAddress)
2018-08-15 20:33:26 -07:00
height = GetHeight()
global = GetGlobal()
pool = GetPool()
ValDistr = GetValidatorDistribution(delegation.ValidatorAddr)
validator = GetValidator(delegation.ValidatorAddr)
2018-08-15 20:33:26 -07:00
// withdraw self-delegation
withdraw = GetDelegatorAllWithdraws(validator.OperatorAddr, height)
2018-08-15 20:33:26 -07:00
// withdrawal validator commission rewards
global, commission = valDistr.WithdrawCommission(global, valDistr, height, pool.BondedTokens,
validator.Tokens, validator.DelegatorShares, validator.Commission)
withdraw += commission
SetGlobal(global)
2018-08-15 20:33:26 -07:00
AddCoins(withdrawAddr, totalEntitlment.TruncateDecimal())
```
2018-08-15 20:33:26 -07:00
2018-08-14 20:33:40 -07:00
## Common calculations
2018-08-08 21:34:19 -07:00
### Update total validator accum
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-14 20:33:40 -07:00
updates each time rewards are withdrawn from the system.
2018-08-08 21:34:19 -07:00
```
2018-08-14 10:45:13 -07:00
func (g Global) UpdateTotalValAccum(height int64, totalBondedTokens Dec)
blocks = height - g.TotalValAccumUpdateHeight
g.TotalValAccum += totalDelShares * blocks
2018-08-15 17:03:39 -07:00
g.TotalValAccumUpdateHeight = height
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
2018-08-14 10:45:13 -07:00
```
func (vd ValidatorDistribution) UpdateTotalDelAccum(height int64, totalDelShares Dec)
blocks = height - vd.TotalDelAccumUpdateHeight
vd.TotalDelAccum += totalDelShares * blocks
2018-08-15 17:03:39 -07:00
vd.TotalDelAccumUpdateHeight = height
2018-08-08 21:34:19 -07:00
```
2018-08-14 20:33:40 -07:00
### Global pool to validator pool
2018-08-08 21:34:19 -07:00
2018-08-15 20:33:26 -07:00
Every time a validator or delegator make a withdraw 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.
2018-08-08 21:34:19 -07:00
```
2018-08-14 20:33:40 -07:00
func (vd ValidatorDistribution) TakeAccum(g Global, height int64, totalBonded, vdTokens Dec) g Global
2018-08-14 10:45:13 -07:00
g.UpdateTotalValAccum(height, totalBondedShares)
2018-08-14 20:33:40 -07:00
g.UpdateValAccum(height, totalBondedShares)
// update the validators pool
blocks = height - vd.GlobalWithdrawalHeight
2018-08-15 17:03:39 -07:00
vd.GlobalWithdrawalHeight = height
2018-08-14 20:33:40 -07:00
accum = blocks * vdTokens
withdrawalTokens := g.Pool * accum / g.TotalValAccum
2018-08-15 01:12:44 -07:00
g.TotalValAccum -= accumm
2018-08-14 20:33:40 -07:00
vd.Pool += withdrawalTokens
g.Pool -= withdrawalTokens
return g
2018-08-08 21:34:19 -07:00
```
2018-08-14 20:33:40 -07:00
### Delegation's withdrawal
2018-08-15 20:33:26 -07:00
For delegations (including validator's self-delegation) all rewards from reward pool
are subject to commission rate from the operator of the validator.
2018-08-08 21:34:19 -07:00
```
2018-08-15 17:03:39 -07:00
func (dd DelegatorDist) WithdrawRewards(g Global, vd ValidatorDistribution,
2018-08-15 20:33:26 -07:00
height int64, totalBonded, vdTokens, totalDelShares, commissionRate Dec) (g Global, withdrawn DecCoins)
2018-08-14 20:33:40 -07:00
2018-08-15 01:12:44 -07:00
vd.UpdateTotalDelAccum(height, totalDelShares)
g = vd.TakeAccum(g, height, totalBonded, vdTokens)
2018-08-14 20:33:40 -07:00
2018-08-15 01:12:44 -07:00
blocks = height - dd.WithdrawalHeight
2018-08-15 17:03:39 -07:00
dd.WithdrawalHeight = height
2018-08-15 01:12:44 -07:00
accum = delegatorShares * blocks * (1 - commissionRate)
2018-08-15 17:03:39 -07:00
withdrawalTokens := vd.Pool * accum / vd.TotalDelAccum
vd.TotalDelAccum -= accum
2018-08-15 01:12:44 -07:00
vd.Pool -= withdrawalTokens
vd.TotalDelAccum -= accum
2018-08-15 17:03:39 -07:00
return g, withdrawalTokens
2018-08-14 20:33:40 -07:00
```
2018-08-14 20:33:40 -07:00
### Validators's commission withdrawal
Similar to a delegator's entitlement, but with recipient shares based on the
commission portion of bonded tokens.
```
2018-08-15 17:03:39 -07:00
func (vd ValidatorDist) WithdrawCommission(g Global, vd ValidatorDistribution,
2018-08-15 20:33:26 -07:00
height int64, totalBonded, vdTokens, totalDelShares, commissionRate Dec) (g Global, withdrawn DecCoins)
2018-08-15 01:12:44 -07:00
vd.UpdateTotalDelAccum(height, totalDelShares)
g = vd.TakeAccum(g, height, totalBonded, vdTokens)
blocks = height - vd.CommissionWithdrawalHeight
2018-08-15 17:03:39 -07:00
vd.CommissionWithdrawalHeight = height
2018-08-15 01:12:44 -07:00
accum = delegatorShares * blocks * (commissionRate)
2018-08-15 17:03:39 -07:00
withdrawalTokens := vd.Pool * accum / vd.TotalDelAccum
vd.TotalDelAccum -= accum
2018-08-15 01:12:44 -07:00
vd.Pool -= withdrawalTokens
vd.TotalDelAccum -= accum
2018-08-15 17:03:39 -07:00
return g, withdrawalTokens
```