# Actor Spec: Reward [Back to Master Tracking Doc](https://hackmd.io/LOZjAsz-THelSD5lWqSVlw) <!-- TODO: Import from source: https://hackmd.io/0v7fuTnmSuiFJ7sfb58h4w --> ## Contents [TOC] ## At a Glance The Reward actor is an Singleton actor which handles rewards distribution. Its main role is to distribute rewards to the miners, while also updating the neccessary state variables that help computing those said rewards. **Actor Type:** - Singleton - Address: 2 **Exported Methods:** 1. Constructor 2. AwardBlockReward 3. ThisEpochReward 4. UpdateNetworkKPI ## State ```go= type State struct { CumsumBaseline Spacetime CumsumRealized Spacetime EffectiveNetworkTime abi.ChainEpoch // The reward to be paid in per WinCount to block producers. // The actual reward total paid out depends on the number of winners in any round. // This value is recomputed every non-null epoch and used in the next non-null epoch. ThisEpochReward abi.TokenAmount // Epoch tracks for which epoch the Reward was computed Epoch abi.ChainEpoch } ``` - **CumsumBaseline:** is a target that **CumsumRealized** needs to reach for **EffectiveNetworkTime** to increase. - **CumsumRealized:** is the cumulative sum of network power capped by **BaselinePower** of epoch - **EffectiveNetworkTime:** is ceiling of real effective network time `theta` based on `CumsumBaselinePower(theta) == CumsumRealizedPower`. Theta captures the notion of how much the network has progressed in its baseline and in advancing network time. - **ThisEpochReward:** ## Exported Methods #### 1. Constructor ```go= func (a Actor) Constructor(rt vmr.Runtime, currRealizedPower *abi.StoragePower) *adt.EmptyValue ``` Initializes the RewardActor state. #### 2. AwardBlockReward ```go= func (a Actor) AwardBlockReward(rt vmr.Runtime, params *AwardBlockRewardParams) *adt.EmptyValue ``` Can only be called by the system actor. On successful execution: * Sends block rewards to the Miner, minus any incurred penalties: * **Epoch Block Reward**: * **Block Gas Reward**: * **Penalties**: * Any `Penalty > 0` is sent to the BurntFunds actor. ##### Parameters ```go= type AwardBlockRewardParams struct { Miner address.Address Penalty abi.TokenAmount // penalty for including bad messages in a block GasReward abi.TokenAmount // gas reward from all gas fees in a block WinCount int64 } ``` **`Miner`**: The address of the Miner receiving the reward. **`Penalty`**: The reward sent to the Miner is reduced by this amount. * Notes: * This value can actually be higher than the `blockReward`, but it is capped by `blockReward`. In this scenario, the `Miner` does not receive any rewards. * Example "bad messages" that will incur a penalty: * Incorrect nonce * `msg.Caller` invalid (not resolvable via init actor table) * `msg.Caller` has insufficient funds to pay for execution **`GasReward`**: The sum of all gas fees in the block. **`WinCount`**: ##### Failure conditions * Caller is not the System actor * ... #### 3. ThisEpochReward ```go= func (a Actor) ThisEpochReward(rt vmr.Runtime, _ *adt.EmptyValue) *abi.TokenAmount ``` Returns the current epoch reward. - Does not change state. - Does not take any parameters. - Can be called by anyone. ##### Return `TokenAmount` is the award value used for the current epoch. ```go= type TokenAmount = big.Int ``` #### 4. UpdateNetworkKPI ```go= func (a Actor) UpdateNetworkKPI(rt vmr.Runtime, currRealizedPower *abi.StoragePower) *adt.EmptyValue ``` Invoked by the StoragePower actor at the end of each non-empty tipset. This method updates internal state for each tipset since the last time it was invoked (`st.Epoch` to `rt.CurrEpoch()`). When updating internal state for tipsets prior to `rt.CurrEpoch()`: * `st.CumsumRealized` is increased by the epoch's realized power, up to a maximum of Baseline Power. * `st.CumsumBaseline` is increased by Baseline Power until it is greater than or equal to `st.CumsumRealized`. * `st.EffectiveNetworkTime` is incremented by 1 for each additional level of Baseline Power added to `st.CumsumBaseline` Finally, `UpdateNetworkKPI` updates state for `rt.CurrEpoch() + 1`, performing the steps described above for `rt.CurrEpoch()`, then setting `st.ThisEpochReward`. Once complete, `st.Epoch` should be `rt.CurrEpoch() + 1`, and `st.ThisEpochReward` should contain the epoch reward for the upcoming epoch. ##### Parameters ```go= currRealizedPower *abi.StoragePower ``` **`currRealizedPower`**: The StoragePower actor's recorded `st.TotalRawBytePower`. * Requirements: * Must not be `nil` ##### Failure conditions * --- ## Recommendations ## Open Questions - In `AwardBlockReward` can the `penalty` which is currently initialized [here](https://github.com/filecoin-project/specs-actors/blob/e5b62bf0f506ec6ea3899fa94dcd4dd701ad51e5/actors/builtin/reward/reward_actor.go#L69) but the initial value is overwritten [here](https://github.com/filecoin-project/specs-actors/blob/e5b62bf0f506ec6ea3899fa94dcd4dd701ad51e5/actors/builtin/reward/reward_actor.go#L83-L84). Could it be initialized directly at line 84? - Because `params.Penalty` is `int`, should it be checked to be `>=0`? - Because `params.GasReward` is `int`, should it be checked to be `>=0`? - Can the number of leaders be different than the `builtin.ExpectedLeadersPerEpoch` value? - For clarification what is `block gas reward` vs `epoch block reward`? - What is the difference between the address resolving done [in multisig](https://github.com/filecoin-project/specs-actors/blob/e5b62bf0f506ec6ea3899fa94dcd4dd701ad51e5/actors/builtin/multisig/multisig_actor.go#L468-L490) vs the one done [here](https://github.com/filecoin-project/specs-actors/blob/e5b62bf0f506ec6ea3899fa94dcd4dd701ad51e5/actors/builtin/reward/reward_actor.go#L62) - Is it possible for the reward to be higher than the current balance of the `RewardActor`? - What is `WinCount`?