Make inactivity leak quadratic per validator
Status quo and problem
Currently, the inactivity leak is computed as follows: in a given epoch, if there has not been finality for d epochs, any validator who is offline during that epoch is penalized d / INACTIVITY_PENALTY_QUOTIENT of their balance.
A major problem with this scheme is that it heavily penalizes honest validators who are online imperfectly: if fully online validators get leaked and lose 40% of their balance, someone who has been trying hard to stay online and succeeds at 90% of their duties would still lose 4% of their balance (approximately; ignoring compounding here for simplicity). Arguably this is unfair.
Proposed fix
Change the inactivity leak rule to the following. For every validator, we maintain a counter epochs_offline_since_finality. When the chain finalizes, this counter is reset to zero; if the chain fails to finalize, and during that epoch the validator is absent, then (i) the validator is penalized epochs_offline_since_finality / INACTIVITY_PENALTY_QUOTIENT of their balance, and (ii) epochs_offline_since_finality increments by 1.
This means that during a leak, each individual validator's penalty is proportional to the square of the number of epochs that they personally have missed. Hence, if a validator who has been fully offline loses 40%, a validator who is online 90% of the time during that same period would only lose 0.4% of their balance, a much smaller amount that they could earn back within weeks of validating after the leak ends.
If validators have multiple duties, then we can rename epochs_offline_since_finality to missed_duties_since_finality and increment it by 1 for each missed duty, and adjust INACTIVITY_PENALTY_QUOTIENT appropriately to ensure the same total burn as today for fully offline validators.
Effects on efficiency
epochs_offline_since_finality can be stored in a separate array, similar to validator balances, for efficiency. During normal (finalizing) periods, this array would not change, so costs would not increase at all. During non-finality, an additional ~8 bytes of hashing per validator would be required (or we could avoid this entirely by mashing together balance and epochs_offline_since_finality into a single variable).
If done in combination with https://github.com/ethereum/eth2.0-specs/issues/1340, efficiency can be maintained because we can still calculate the correct penalty for each validator if they had a previous epochs_offline_since_finality and were offline for N epochs: log(balance) -= (epochs_offline_since_finality + (N-1)/2) * N / INACTIVITY_PENALTY_QUOTIENT (any desired accuracy can be achieved with Taylor approximations of log/exp).
Related: #2098
I am closing this issue because it seems stale. Please, do not hesitate to reopen it if this is a mistake