-
Notifications
You must be signed in to change notification settings - Fork 971
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mitigating attacks on light clients #403
Comments
The Add
(Notice that updates to |
Workable, but having three validator state arrays is definitely not the best thing..... |
Do you mean from an aesthetic point of view? I does save from adding various bits and pieces to the
|
Would the |
I'm ok with it from an aesthetic point of view, it's more that the state size goes up yet again (we can mitigate this by storing indices and not pubkeys, but still.....). |
There are four events that trigger a validator set change 1) activations 2) exits 3) ejections 4) penalizations. All but penalizations happen at epoch boundaries. I'm therefore tempted to make the validator set change also happen at epoch boundaries. (Specifically, in
A full pass through the validator registry is never required to update
Having light clients know at least
The reason I went with pubkeys as opposed to indices is so that light-clients don't have to bother with |
Right but my point is that if we do it that way, then the
True, though for security we would need to add That said, this would lead to light clients needing to download a bunch of Merkle branches, at which point it's not clear that this approach to light clients is even better than the old approach of requiring them to store and update the entire validator set and use that to calculate committees..... |
Closing in favour of #459 :) |
Light clients could theoretically verify the beacon chain with a reasonable degree of security at very low cost by verifying only one crosslink committee per epoch, or even more rarely. However, at present this approach is has a few key weaknesses.
First, it requires the light client to track the entire validator set (up to ~800 MB of state in the worst case), to be able to compute the validator shuffling. Note that alternative shuffling algos do not fix this problem, because the step of filtering out inactive validators still requires a pass through the entire validator set.
Second, it is potentially insecure, because of the following attack. A validator could choose a seed, compute the validator set shuffle assuming a particular validator set size, and then selectively censor validator set changes to make the shuffle match up with their subset. For example, if an attacker has all validator slots with IDs 0 mod 10 (for simplicity, realistically they might have a more chaotic combination with similar spacing), then to make a randomly selected committee of 128 match up with them, then as long as at least 9 validators activated or exited between each selected committee member and the next, they could selectively censor those activations and exits to make the committee match up perfectly with their own validators.
We can solve these issues as follows. First, we can keep track of the last four epoch-boundary
validator_registry
andvalidator_balances
root hashes in the state, and we can mix the fourth last one (ie. the same one from where the validator set comes) into the shuffling seed. This means that the shuffling will now depend on the exact validator set used, so it will not be possible to manipulate the validator set to target a specific shuffling that the attacker already knows.Second, in addition to adopting the number-theoretic or other pointwise-evaluable shuffle, we can remove the need for the validator set filtering step as follows. We keep track of another two arrays in the state, one for the historical total length of the validator set, the other for the historical length of the active validator set size. For attack mitigation reasons we can mix both of these values into the shuffling seed as well.
We compute the shuffle over
[0...total_length-1]
(so it includes all validators, not distinguishing active and inactive). To restrict the shuffle to active validators, we reuse the trick that we used to create number-theoretic shuffles for arbitrary lengths: ifp
is the permutation function over[0...total_length-1]
, then to calculate the actual permutation forx
we first tryp(x)
, then ifp(x)
is not a valid result tryp(p(x))
, if still incorrect tryp(p(p(x)))
, etc (in practice, "not a valid result" means "is not an active validator" if evaluating the shuffle in one direction, and "is less than the active validator count" in the other direction).Now, a light client can skip ahead by asking for a future block header, use the information in the block header to compute the indices for a committee, ask for Merkle branches to prove the committee, and then ask for those same Merkle branches of the validator set the client already knows about to verify that the validator set has not changed too much.
The text was updated successfully, but these errors were encountered: