Prevent gossip of duplicate exits, slashings, BLS #5375
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Issue Addressed
Some of the other clients have pulled us up for propagating duplicate exits, slashings and BLS to execution changes on gossip. The reason for this is that Lighthouse only checks for duplicates against an in-memory cache which is cleared on restart.
Proposed Changes
This PR fixes the issue by checking for duplicate exits/slashings/address-change messages against the head state. E.g. if a validator is already exited in the state then we consider new exits for this validator as duplicates, and similarly for other messages.
There are 2 broad approaches I considered when fixing this issue, with different trade-offs.
Option 1: check against head state
This is the approach taken by this PR. With flat (not tree) states its performance is:
O(1)
per validator, indexing into theBeaconState
.O(1)
. No additional storage beyond the state is required.However with
tree-states
these random indexing operations will become more expensive, at which point we may want to reconsider:O(log n)
per validator for indexing into theBeaconState
.O(1)
.Option 2: restore the cache on startup
There's a TODO in the code that's been there forever about reinitialising some of these caches on startup:
lighthouse/beacon_node/beacon_chain/src/builder.rs
Lines 911 to 936 in b5bae6e
Rather than storing them on disk independently, we could reconstruct them from the head state. This has the advantage of providing
O(1)
indexing withtree-states
, at the cost of slightly more memory:O(1)
for indexing into theHashSet
insideObservedOperations
.O(n)
wheren
is the number of slashed/exited validators.With
tree-states
we could also take a hybrid approach, e.g. using theslashings_cache
introduced in #5279 to check for slashings, and initialising the exit cache on startup so that it indexes inO(1)
.The complication would be making this work with
reset_at_fork_boundary
, which would probably have to do a full re-initialisation at each fork boundary (potentially very slow).Additional Info
Thanks to @nisdas from Prysm for tracking these invalid messages down to Lighthouse peers, and for suggesting a fix (Prysm had a similar issue until recently and fixed it by using the head state).