Remove the current concept of effective vs current balance. Instead, keep (i) the balance inside the validator struct, and (ii) a counter of "duties fulfilled". Accounting for (ii) would be very simple: did you get the correct source? Add 1. Correct target? Add 1. Timely? Add 1.
Every 256 epochs (can be staggered), we update the validator balance based on the duties fulfilled count, and reset the duties fulfilled count. The inactivity leak is also implemented at this stage. Note that this comes at the cost of some coarseness: if an inactivity leak starts halfway through a period, offlineness before and after the start of the leak is equally penalized (if we want to remove this entirely, we could also have two duties counters, one for leaking periods and one for non-leaking periods).
This lets us remove hysteresis, and additionally makes it much easier to implement https://github.com/ethereum/eth2.0-specs/issues/2125/mp3 juice (quadratic leak per validator) and https://github.com/ethereum/eth2.0-specs/issues/1340/tubidy (optimized empty epoch processing).
Further down the line, the simpler math of duties accounting potentially makes it easier to do cryptographic optimizations. The most extreme is ZK-proving this entire part of the transition, but there is also a simpler path: use a Kate commitment instead of a Merkle tree to store duties, so duties accounting would only require ~2 ECADDs, not an ECMUL, per validator, and could be done in real-time instead of waiting for the end of an epoch!
Sidenote: if we do Kate commitments, then it becomes more challenging to have a
Implement https://github.com/ethereum/eth2.0-specs/issues/2125. Increases "friendliness" to honest-but-imperfect validators during a leak (eg. a validator that is online 95% of the time during a leak where malicious validators lose 40% would lose 0.1% of their deposit instead of 2%).
Implement https://github.com/ethereum/eth2.0-specs/issues/1340/y2mate (modified as appropriate for the new duties accounting). Ensures that non-canonical chains with few proposers and many skipped slots are easier to process.
Right now (in phase 0 + future proposals) we have many pairs of the form (current_epoch_thing
, previous_epoch_thing
). This creates unnecessary code duplication. Instead, we should have a struct ActiveEpochData
which contains all of the data that is stored in these structures, and in the beacon state we simply have current_epoch_data
and previous_epoch_data
.
In the event that >1M validators are active, come up with a way to randomly select some to be active and turn the others off (ie. don't give them rewards and allow them to drop offline). This serves two functions:
One potential path to implementing this is https://github.com/ethereum/eth2.0-specs/issues/2137