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  ```