github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/distribution/spec/04_messages.md (about) 1 <!-- 2 order: 4 3 --> 4 5 # Messages 6 7 ## MsgWithdrawDelegationRewardsAll 8 9 When a delegator wishes to withdraw their rewards it must send 10 `MsgWithdrawDelegationRewardsAll`. Note that parts of this transaction logic are also 11 triggered each with any change in individual delegations, such as an unbond, 12 redelegation, or delegation of additional tokens to a specific validator. 13 14 ```go 15 type MsgWithdrawDelegationRewardsAll struct { 16 DelegatorAddr sdk.AccAddress 17 } 18 19 func WithdrawDelegationRewardsAll(delegatorAddr, withdrawAddr sdk.AccAddress) 20 height = GetHeight() 21 withdraw = GetDelegatorRewardsAll(delegatorAddr, height) 22 SendCoins(distributionModuleAcc, withdrawAddr, withdraw.TruncateDecimal()) 23 24 func GetDelegatorRewardsAll(delegatorAddr sdk.AccAddress, height int64) DecCoins 25 26 // get all distribution scenarios 27 delegations = GetDelegations(delegatorAddr) 28 29 // collect all entitled rewards 30 withdraw = 0 31 pool = staking.GetPool() 32 feePool = GetFeePool() 33 for delegation = range delegations 34 delInfo = GetDelegationDistInfo(delegation.DelegatorAddr, 35 delegation.ValidatorAddr) 36 valInfo = GetValidatorDistInfo(delegation.ValidatorAddr) 37 validator = GetValidator(delegation.ValidatorAddr) 38 39 feePool, diWithdraw = delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens, 40 validator.Tokens, validator.DelegatorShares, validator.Commission) 41 withdraw += diWithdraw 42 43 SetFeePool(feePool) 44 return withdraw 45 ``` 46 47 ## MsgWithdrawDelegationReward 48 49 under special circumstances a delegator may wish to withdraw rewards from only 50 a single validator. 51 52 ```go 53 type MsgWithdrawDelegationReward struct { 54 DelegatorAddr sdk.AccAddress 55 ValidatorAddr sdk.ValAddress 56 } 57 58 func WithdrawDelegationReward(delegatorAddr, validatorAddr, withdrawAddr sdk.AccAddress) 59 height = GetHeight() 60 61 // get all distribution scenarios 62 pool = staking.GetPool() 63 feePool = GetFeePool() 64 delInfo = GetDelegationDistInfo(delegatorAddr, 65 validatorAddr) 66 valInfo = GetValidatorDistInfo(validatorAddr) 67 validator = GetValidator(validatorAddr) 68 69 feePool, withdraw = delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens, 70 validator.Tokens, validator.DelegatorShares, validator.Commission) 71 72 SetFeePool(feePool) 73 SendCoins(distributionModuleAcc, withdrawAddr, withdraw.TruncateDecimal()) 74 ``` 75 76 77 ## MsgWithdrawValidatorRewardsAll 78 79 When a validator wishes to withdraw their rewards it must send 80 `MsgWithdrawValidatorRewardsAll`. Note that parts of this transaction logic are also 81 triggered each with any change in individual delegations, such as an unbond, 82 redelegation, or delegation of additional tokens to a specific validator. This 83 transaction withdraws the validators commission fee, as well as any rewards 84 earning on their self-delegation. 85 86 ```go 87 type MsgWithdrawValidatorRewardsAll struct { 88 OperatorAddr sdk.ValAddress // validator address to withdraw from 89 } 90 91 func WithdrawValidatorRewardsAll(operatorAddr, withdrawAddr sdk.AccAddress) 92 93 height = GetHeight() 94 feePool = GetFeePool() 95 pool = GetPool() 96 ValInfo = GetValidatorDistInfo(delegation.ValidatorAddr) 97 validator = GetValidator(delegation.ValidatorAddr) 98 99 // withdraw self-delegation 100 withdraw = GetDelegatorRewardsAll(validator.OperatorAddr, height) 101 102 // withdrawal validator commission rewards 103 feePool, commission = valInfo.WithdrawCommission(feePool, valInfo, height, pool.BondedTokens, 104 validator.Tokens, validator.Commission) 105 withdraw += commission 106 SetFeePool(feePool) 107 108 SendCoins(distributionModuleAcc, withdrawAddr, withdraw.TruncateDecimal()) 109 ``` 110 111 ## Common calculations 112 113 ### Update total validator accum 114 115 The total amount of validator accum must be calculated in order to determine 116 the amount of pool tokens which a validator is entitled to at a particular 117 block. The accum is always additive to the existing accum. This term is to be 118 updated each time rewards are withdrawn from the system. 119 120 ```go 121 func (g FeePool) UpdateTotalValAccum(height int64, totalBondedTokens Dec) FeePool 122 blocks = height - g.TotalValAccumUpdateHeight 123 g.TotalValAccum += totalDelShares * blocks 124 g.TotalValAccumUpdateHeight = height 125 return g 126 ``` 127 128 ### Update validator's accums 129 130 The total amount of delegator accum must be updated in order to determine the 131 amount of pool tokens which each delegator is entitled to, relative to the 132 other delegators for that validator. The accum is always additive to 133 the existing accum. This term is to be updated each time a 134 withdrawal is made from a validator. 135 136 ``` go 137 func (vi ValidatorDistInfo) UpdateTotalDelAccum(height int64, totalDelShares Dec) ValidatorDistInfo 138 blocks = height - vi.TotalDelAccumUpdateHeight 139 vi.TotalDelAccum += totalDelShares * blocks 140 vi.TotalDelAccumUpdateHeight = height 141 return vi 142 ``` 143 144 ### FeePool pool to validator pool 145 146 Every time a validator or delegator executes a withdrawal or the validator is 147 the proposer and receives new tokens, the relevant validator must move tokens 148 from the passive global pool to their own pool. It is at this point that the 149 commission is withdrawn 150 151 ```go 152 func (vi ValidatorDistInfo) TakeFeePoolRewards(g FeePool, height int64, totalBonded, vdTokens, commissionRate Dec) ( 153 vi ValidatorDistInfo, g FeePool) 154 155 g.UpdateTotalValAccum(height, totalBondedShares) 156 157 // update the validators pool 158 blocks = height - vi.FeePoolWithdrawalHeight 159 vi.FeePoolWithdrawalHeight = height 160 accum = blocks * vdTokens 161 withdrawalTokens := g.Pool * accum / g.TotalValAccum 162 commission := withdrawalTokens * commissionRate 163 164 g.TotalValAccum -= accumm 165 vi.PoolCommission += commission 166 vi.PoolCommissionFree += withdrawalTokens - commission 167 g.Pool -= withdrawalTokens 168 169 return vi, g 170 ``` 171 172 173 ### Delegation reward withdrawal 174 175 For delegations (including validator's self-delegation) all rewards from reward 176 pool have already had the validator's commission taken away. 177 178 ```go 179 func (di DelegationDistInfo) WithdrawRewards(g FeePool, vi ValidatorDistInfo, 180 height int64, totalBonded, vdTokens, totalDelShares, commissionRate Dec) ( 181 di DelegationDistInfo, g FeePool, withdrawn DecCoins) 182 183 vi.UpdateTotalDelAccum(height, totalDelShares) 184 g = vi.TakeFeePoolRewards(g, height, totalBonded, vdTokens, commissionRate) 185 186 blocks = height - di.WithdrawalHeight 187 di.WithdrawalHeight = height 188 accum = delegatorShares * blocks 189 190 withdrawalTokens := vi.Pool * accum / vi.TotalDelAccum 191 vi.TotalDelAccum -= accum 192 193 vi.Pool -= withdrawalTokens 194 vi.TotalDelAccum -= accum 195 return di, g, withdrawalTokens 196 197 ``` 198 199 ### Validator commission withdrawal 200 201 Commission is calculated each time rewards enter into the validator. 202 203 ```go 204 func (vi ValidatorDistInfo) WithdrawCommission(g FeePool, height int64, 205 totalBonded, vdTokens, commissionRate Dec) ( 206 vi ValidatorDistInfo, g FeePool, withdrawn DecCoins) 207 208 g = vi.TakeFeePoolRewards(g, height, totalBonded, vdTokens, commissionRate) 209 210 withdrawalTokens := vi.PoolCommission 211 vi.PoolCommission = 0 212 213 return vi, g, withdrawalTokens 214 ```