Substrate: How to estimate validator and nominator rewards?

Created on 1 Mar 2019  路  9Comments  路  Source: paritytech/substrate

Is there any documentations available anywhere about how block reward is calculated?
It will be good if there is a way to calculate ROI.

I5-documentation 馃搫

Most helpful comment

This is some nice brain food. Let's see.

Note that I am answering this based on https://github.com/paritytech/substrate/pull/1915 which is not yet merged but I believe it is not that far. With this PR, nominators' vote plays a significant role in the staking system and basically their staked value is the one and only measure of electing validators (technically _the value that the validator has in stake does not play any role regarding being elected_; it does matter for the reward though).

I will base all the below answer based on all stakers not forwarding their rewards to their staked account. Otherwise, this will change _slot stake_ which then affects _session reward_ which makes the answer to this another step harder. Though, note that the same logic applies if _slot stake_ changes. Slot stake is the minimum staked value among all stakers in the system and the reward of each session is slot_stake multiplied by a ration which in this case you defined to be 0.1%.

  1. This is good to discuss but completely in the gray zone. First I have to discuss the situation where nominators are scarce. The Staking Module defines two storage configs: ValidatorCount and MinimumValidatorCount. With the current implementation, all validators are first filtered by having a non-zero and positiveapproval_score, which is the sum of the staked fund of all nominators who voted for this particular validator. Next:

    • If the number of available validators with this filter is more than ValidatorCount: Normal election algorithm executes and ValidatorCount validators are chosen (I call this _code green/white_).

    • If the number of available validators with this filter is less than ValidatorCount but more than MinimumValidatorCount: All of them are elected, and nominators who voted for this elected set are also recorded. (I call this _code yellow_)

    • if the number of available validators with this filter is less than ValidatorCount and MinimumValidatorCount, Nothing happens. The previous generation of validators remain in duty and more importantly, the nominator votes are not taken into account at all (meaning that potentially the next era reward will not be shared -- I call this _code red_).

Now, to properly answer 1, it must first become clear which of the above is the case for the 4 aforementioned validators.

To be a good complement of your question 2, I will assume _code red_, meaning that 4 validators are chosen and they DO NOT SHARE anything with anyone else. The calculation will be as follows:

Ignoring the first round, the session reward will be calculated with your numbers as:

// current_session_reward = concrete value of reward 
// session_reward = the ratio
current_session_reward = slot_stake * session_reward
// if block production is on-time
current_era_reward = era_length * current_session_reward 

Hence,

1_000_000 * 0.001 = 1000. This is because slot_stake == 1_000_000. With 5 sessions to get the actual reward, each validator will be paid 5000 per era. Since I've assumed constant slot_stake, this should not change and the same reward should be paid henceforth.

Is the session reward calculated as 1000000 * 0.1% for one validators? Or it is for all validators?

Yes (given all the conditions above) and this is paid Per Validator.

  1. I will assume:

    • Again, slot_stake is constant and is the minimum that all entities have in stake. Let's change
      > 4 nominators nominate each validator 1000 1_000_000 tokens.

    to all nominators placing also 1_000_000 in stake, otherwise session reward will be 1 and not that interesting anymore to be divided in an environment where no float calculation can be executed.

Ignoring the first round, the session reward will be calculated as 1_000_000 * 0.001 = 1000. Note that by this point the staking system does not even take into account if nominators/validator_cut exist or not. Similarly, 5000 is recorded at the end of the era and should be distributed. To illustrate how, this struct _kinda_ shows the exposure of each validator at the end of the era:

{ 
    total: 5_000_000, 
    own: 1_000_000, 
    others: [ {who: N1, 1000_000}, {who: N2, 1000_000}, {who: N3, 1000_000}, {who: N4, 1000_000}]
}

And they are each rewarded by a ratio of the total 5000, proportional to what they contribute to exposure.total == 5_000_000. In this case, it will be all even with 1/5 share for everyone. Hence, each validator will get 5000 / 5 => 1_000 per era, same for nominators.

Finally, since you mentioned that each nominator will vote for all of the selected 4 validators, this means that at the end of the era, each nominator gets rewarded 4 times for each of its elected validators. Hence, the total reward for a nominator will be 4000 per era.

  1. Going offline will not

    • affect the reward for the rest of the validators.

    • It will also not affect the reward of the validator that went offline. The first N offline reports are _grace_ and once it reaches the threshold, it will be slashed and kicked out. This might raise the question of how much is the slash for each validator and nominators but I will leave this for another comment.

    • What will affect the rewards (of _all_ validators) is the timeliness of block production. But I will leave this also for another comment.

I don't think a spreadsheet is a good idea for now. Ideally, I will formulate a gist of this in the staking module's documentation and anyone can be able to create an implementation in the form of a script or a spreadsheet.

All 9 comments

I will soon publish a small document about the Staking Module which should answer this question; not yet written but I actually have a section dedicated to explaining how the reward and slash value is calculated + shared among validator and nominators.

at the moment the test cases are the only resource.

And One way or another this issue/question suits https://github.com/paritytech/substrate-developer-hub better than here.

@Kianenigma this repository is private and not visible for non-parity members.

@xlc Please see if this answers your question.

@Kianenigma I don't think it answers all my questions.
More specifically:

  1. With 4 validators, each have 1000000 tokens, and session reward of 0.1%, session length of 10 blocks, era length of 5 sessions, all 100% availability, what is the expected rewards for each validators per session, and per era? Is the session reward calculated as 1000000 * 0.1% for one validators? Or it is for all validators?
  2. With same scenario as above, 4 nominators nominate each validator 1000 tokens, assuming validator does not take any cut, what is the expected rewards for each validators and nominators per session, and per era?
  3. With same scenario as 1, one validator offline once per era, what is the expected reward for this validator and others that always available?

Basically I want some formulas that can be used to calculate ROI for validators and nominators. If I invest 100000 DOTs to become a validator or nominator, how many DOTs do I expected to make per year? What if my (or the validator I nominate to) availability is 99%, what is the expected reward? To what point I will start losing DOTs due to off-line slash more than rewards?

Some spreadsheet that allow me to enter values and getting estimations will be very help.

This is some nice brain food. Let's see.

Note that I am answering this based on https://github.com/paritytech/substrate/pull/1915 which is not yet merged but I believe it is not that far. With this PR, nominators' vote plays a significant role in the staking system and basically their staked value is the one and only measure of electing validators (technically _the value that the validator has in stake does not play any role regarding being elected_; it does matter for the reward though).

I will base all the below answer based on all stakers not forwarding their rewards to their staked account. Otherwise, this will change _slot stake_ which then affects _session reward_ which makes the answer to this another step harder. Though, note that the same logic applies if _slot stake_ changes. Slot stake is the minimum staked value among all stakers in the system and the reward of each session is slot_stake multiplied by a ration which in this case you defined to be 0.1%.

  1. This is good to discuss but completely in the gray zone. First I have to discuss the situation where nominators are scarce. The Staking Module defines two storage configs: ValidatorCount and MinimumValidatorCount. With the current implementation, all validators are first filtered by having a non-zero and positiveapproval_score, which is the sum of the staked fund of all nominators who voted for this particular validator. Next:

    • If the number of available validators with this filter is more than ValidatorCount: Normal election algorithm executes and ValidatorCount validators are chosen (I call this _code green/white_).

    • If the number of available validators with this filter is less than ValidatorCount but more than MinimumValidatorCount: All of them are elected, and nominators who voted for this elected set are also recorded. (I call this _code yellow_)

    • if the number of available validators with this filter is less than ValidatorCount and MinimumValidatorCount, Nothing happens. The previous generation of validators remain in duty and more importantly, the nominator votes are not taken into account at all (meaning that potentially the next era reward will not be shared -- I call this _code red_).

Now, to properly answer 1, it must first become clear which of the above is the case for the 4 aforementioned validators.

To be a good complement of your question 2, I will assume _code red_, meaning that 4 validators are chosen and they DO NOT SHARE anything with anyone else. The calculation will be as follows:

Ignoring the first round, the session reward will be calculated with your numbers as:

// current_session_reward = concrete value of reward 
// session_reward = the ratio
current_session_reward = slot_stake * session_reward
// if block production is on-time
current_era_reward = era_length * current_session_reward 

Hence,

1_000_000 * 0.001 = 1000. This is because slot_stake == 1_000_000. With 5 sessions to get the actual reward, each validator will be paid 5000 per era. Since I've assumed constant slot_stake, this should not change and the same reward should be paid henceforth.

Is the session reward calculated as 1000000 * 0.1% for one validators? Or it is for all validators?

Yes (given all the conditions above) and this is paid Per Validator.

  1. I will assume:

    • Again, slot_stake is constant and is the minimum that all entities have in stake. Let's change
      > 4 nominators nominate each validator 1000 1_000_000 tokens.

    to all nominators placing also 1_000_000 in stake, otherwise session reward will be 1 and not that interesting anymore to be divided in an environment where no float calculation can be executed.

Ignoring the first round, the session reward will be calculated as 1_000_000 * 0.001 = 1000. Note that by this point the staking system does not even take into account if nominators/validator_cut exist or not. Similarly, 5000 is recorded at the end of the era and should be distributed. To illustrate how, this struct _kinda_ shows the exposure of each validator at the end of the era:

{ 
    total: 5_000_000, 
    own: 1_000_000, 
    others: [ {who: N1, 1000_000}, {who: N2, 1000_000}, {who: N3, 1000_000}, {who: N4, 1000_000}]
}

And they are each rewarded by a ratio of the total 5000, proportional to what they contribute to exposure.total == 5_000_000. In this case, it will be all even with 1/5 share for everyone. Hence, each validator will get 5000 / 5 => 1_000 per era, same for nominators.

Finally, since you mentioned that each nominator will vote for all of the selected 4 validators, this means that at the end of the era, each nominator gets rewarded 4 times for each of its elected validators. Hence, the total reward for a nominator will be 4000 per era.

  1. Going offline will not

    • affect the reward for the rest of the validators.

    • It will also not affect the reward of the validator that went offline. The first N offline reports are _grace_ and once it reaches the threshold, it will be slashed and kicked out. This might raise the question of how much is the slash for each validator and nominators but I will leave this for another comment.

    • What will affect the rewards (of _all_ validators) is the timeliness of block production. But I will leave this also for another comment.

I don't think a spreadsheet is a good idea for now. Ideally, I will formulate a gist of this in the staking module's documentation and anyone can be able to create an implementation in the form of a script or a spreadsheet.

Bringing this up to mention that the logic here as changed significantly, should be re-documented in the future. cc @thiolliere

logic hasn't change except the total reward per era and the how this total payout is distributed between validator and there associated nominator.

the total payout per era is computed using the current stake rate in npos (stake by validators and nominator / total tokens) and the era duration. See more about this function see more here: https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#inflation-model

then once this total payout is computed it is distributed between validator not equally as it was the case before but depending on action that happen during the era. During the era ppl gets point if they produce a block (20 points), make a validity statement for parachain (20 points), reference an uncle (2 points), produce a referenced uncle (1 points).
(validity statement will be implemented on polkadot side).
See more here https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#payment-details

Closing as I see both the Staking code and web3 research pages covering the topic sufficiently

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xlc picture xlc  路  5Comments

tomaka picture tomaka  路  4Comments

qalqi picture qalqi  路  3Comments

jiangfuyao picture jiangfuyao  路  3Comments

athei picture athei  路  4Comments