The beacon chain maintains two separate records of each validator's balance: its actual balance and its effective balance - Ben Edgington's "Upgrading Ethereum" on Balances
A validator's actual balance
Actual balance is stored in the BeaconState
records, as a registry of validators and their balances:
Actual balance is fine-grained;
Units: Gwei ( ETH)
A validator's effective balance is derived from its actual balance.
Effective balance is stored in the Validator
's records:
Effective balance is much more granular than actual balance;
Units: EFFECTIVE_BALANCE_INCREMENT
( Gwei = 1 ETH)
Effective balance is changed according to a process with hysteresis to avoid situations where it might change frequently.
Effective balances are guaranteed to update much less frequently than actual balance, by using hysteresis in their calculation, so that there's a lag in the reaction time of the output (effective balance), based on the variation of the input (actual balance)
The hysteresis levels are controlled by the hysteresis parameters in the consensus-specs:
Name | Value |
---|---|
HYSTERESIS_QUOTIENT |
uint64(4) |
HYSTERESIS_DOWNWARD_MULTIPLIER |
uint64(1) |
HYSTERESIS_UPWARD_MULTIPLIER |
uint64(5) |
The parameters are used at the end of every epoch at effective balance updates, when the effective balance of all validators present in the BeaconState
's registry (either active or not) is updated by the following rules:
If actual balance is less than effective balance minus HYSTERESIS_DOWNWARD_MULTIPLIER
/ HYSTERESIS_QUOTIENT
(0.25), then reduce effective balance by one EFFECTIVE_BALANCE_INCREMENT
If actual balance is more than effective balance plus HYSTERESIS_UPWARD_MULTIPLIER
/ HYSTERESIS_QUOTIENT
(1.25), then increase effective balance by one EFFECTIVE_BALANCE_INCREMENT
The actual code in the specs (Electra fork):
A validator's effective balance represents its weight in the consensus protocol, the following consensus-related quantities being proportional to its effective balance:
The following rewards, penalties, and punishments are also weighted by effective balance:
Reason : a validator's probability of being selected to propose is proportional to its effective balance, so there's no need to scale the reward itself with the effective balance.
A Validator's effective balance updates much more rarely than actual balance, because it is granular and has hysteresis applied to any updates. This allows validator records inside the beacon state, a large data structure, to be cached and Merkelized less often, improving performance when generating the hash tree root of the entire state. If we would keep the more frequently changing actual balances in the validator's records, the whole data structure would need to be rehashed at least once per epoch.
All rewards are calculated in terms of a "base reward per increment":
Because effective balances are updated only once per epoch, we only need to calculate the base reward per increment once, then cache the result for the whole epoch, irrespective of any changes in actual balances.
get_expected_withdrawals
process_withdrawals