From 05a35c7228f0ae12c44e46cb1d202c6989af434e Mon Sep 17 00:00:00 2001 From: Justin Date: Mon, 10 Jun 2019 15:14:32 +0100 Subject: [PATCH] Tweak inclusion delay rewards and set BASE_REWARD_FACTOR Substantive changes: 1) Split the inclusion delay reward between attester and proposer to add up to at most one base reward. This is analogous to the reward logic in `slash_validator`, and makes the `BASE_REWARDS_PER_EPOCH` constant include proposer rewards. 2) Double `BASE_REWARD_FACTOR` to 2^6 (addressing item 4 in #1054). When the total effective balance is 2^17 ETH then maximum annual issuance is a bit below 2^21 ETH. Maximum annual issuance happens when a) all validators make perfect attestations (matching source, target, head, as well as consistent crosslink data), b) all attestations are included as fast as possible (in particular, no skip blocks), and c) there are no slashings. ```python BASE_REWARD_FACTOR = 2**6 SLOTS_PER_EPOCH = 2**6 SECONDS_PER_SLOT = 6 BASE_REWARDS_PER_EPOCH = 5 GWEI_PER_ETH = 10**9 MAX_TOTAL_EFFECTIVE_BALANCE = 2**27 * GWEI_PER_ETH TARGET_MAX_ISSUANCE = 2**21 * GWEI_PER_ETH def integer_squareroot(n: int) -> int: """ The largest integer ``x`` such that ``x**2`` is less than or equal to ``n``. """ assert n >= 0 x = n y = (x + 1) // 2 while y < x: x = y y = (x + n // x) // 2 return x MAX_REWARDS_PER_EPOCH = MAX_TOTAL_EFFECTIVE_BALANCE * BASE_REWARD_FACTOR // integer_squareroot(MAX_TOTAL_EFFECTIVE_BALANCE) // BASE_REWARDS_PER_EPOCH EPOCHS_PER_YEAR = 365.25*24*60*60 / (SECONDS_PER_SLOT * SLOTS_PER_EPOCH) MAX_REWARDS_PER_YEAR = EPOCHS_PER_YEAR * MAX_REWARDS_PER_EPOCH * BASE_REWARDS_PER_EPOCH print(MAX_REWARDS_PER_YEAR / TARGET_MAX_ISSUANCE) ``` --- specs/core/0_beacon-chain.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index a6d9d23c5..8a60b6f34 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -224,14 +224,13 @@ These configurations are updated for releases, but may be out of sync during `de | Name | Value | | - | - | -| `BASE_REWARD_FACTOR` | `2**5` (= 32) | +| `BASE_REWARD_FACTOR` | `2**6` (= 64) | | `WHISTLEBLOWING_REWARD_QUOTIENT` | `2**9` (= 512) | | `PROPOSER_REWARD_QUOTIENT` | `2**3` (= 8) | | `INACTIVITY_PENALTY_QUOTIENT` | `2**25` (= 33,554,432) | | `MIN_SLASHING_PENALTY_QUOTIENT` | `2**5` (= 32) | -* **The `BASE_REWARD_FACTOR` is NOT final. Once all other protocol details are finalized, it will be adjusted to target a theoretical maximum total issuance of `2**21` ETH per year if `2**27` ETH is validating (and therefore `2**20` per year if `2**25` ETH is validating, etc.)** -* The `INACTIVITY_PENALTY_QUOTIENT` equals `INVERSE_SQRT_E_DROP_TIME**2` where `INVERSE_SQRT_E_DROP_TIME := 2**12 epochs` (~18 days) is the time it takes the inactivity penalty to reduce the balance of non-participating [validators](#dfn-validator) to about `1/sqrt(e) ~= 60.6%`. Indeed, the balance retained by offline [validators](#dfn-validator) after `n` epochs is about `(1 - 1/INACTIVITY_PENALTY_QUOTIENT)**(n**2/2)` so after `INVERSE_SQRT_E_DROP_TIME` epochs it is roughly `(1 - 1/INACTIVITY_PENALTY_QUOTIENT)**(INACTIVITY_PENALTY_QUOTIENT/2) ~= 1/sqrt(e)`. +* The `INACTIVITY_PENALTY_QUOTIENT` equals `INVERSE_SQRT_E_DROP_TIME**2` where `INVERSE_SQRT_E_DROP_TIME := 2**12 epochs` (about 18 days) is the time it takes the inactivity penalty to reduce the balance of non-participating [validators](#dfn-validator) to about `1/sqrt(e) ~= 60.6%`. Indeed, the balance retained by offline [validators](#dfn-validator) after `n` epochs is about `(1 - 1/INACTIVITY_PENALTY_QUOTIENT)**(n**2/2)` so after `INVERSE_SQRT_E_DROP_TIME` epochs it is roughly `(1 - 1/INACTIVITY_PENALTY_QUOTIENT)**(INACTIVITY_PENALTY_QUOTIENT/2) ~= 1/sqrt(e)`. ### Max operations per block @@ -1425,8 +1424,10 @@ def get_attestation_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]: a for a in matching_source_attestations if index in get_attesting_indices(state, a.data, a.aggregation_bitfield) ], key=lambda a: a.inclusion_delay) - rewards[attestation.proposer_index] += get_base_reward(state, index) // PROPOSER_REWARD_QUOTIENT - rewards[index] += get_base_reward(state, index) * MIN_ATTESTATION_INCLUSION_DELAY // attestation.inclusion_delay + proposer_reward = get_base_reward(state, index) // PROPOSER_REWARD_QUOTIENT + rewards[attestation.proposer_index] += proposer_reward + max_attester_reward = get_base_reward(state, index) - proposer_reward + rewards[index] += max_attester_reward * MIN_ATTESTATION_INCLUSION_DELAY // attestation.inclusion_delay # Inactivity penalty finality_delay = previous_epoch - state.finalized_epoch