Is there any documentations available anywhere about how block reward is calculated?
It will be good if there is a way to calculate ROI.
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:
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%.
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:ValidatorCount: Normal election algorithm executes and ValidatorCount validators are chosen (I call this _code green/white_).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_)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.
I will assume:
slot_stake is constant and is the minimum that all entities have in stake. Let's changeto 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.
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.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
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_stakemultiplied by a ration which in this case you defined to be 0.1%.ValidatorCountandMinimumValidatorCount. 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:ValidatorCount: Normal election algorithm executes andValidatorCountvalidators are chosen (I call this _code green/white_).ValidatorCountbut more thanMinimumValidatorCount: All of them are elected, and nominators who voted for this elected set are also recorded. (I call this _code yellow_)ValidatorCountandMinimumValidatorCount, 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:
Hence,
1_000_000 * 0.001 = 1000. This is becauseslot_stake == 1_000_000. With 5 sessions to get the actual reward, each validator will be paid5000per era. Since I've assumed constantslot_stake, this should not change and the same reward should be paid henceforth.Yes (given all the conditions above) and this is paid Per Validator.
I will assume:
slot_stakeis constant and is the minimum that all entities have in stake. Let's change> 4 nominators nominate each validator
10001_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_cutexist or not. Similarly,5000is 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:And they are each rewarded by a ratio of the total
5000, proportional to what they contribute toexposure.total == 5_000_000. In this case, it will be all even with 1/5 share for everyone. Hence, each validator will get5000 / 5 => 1_000per 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
4000per era.Noffline 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.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.