-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Cheaper signature verifcation for incoming blocks #1339
Comments
This may no longer be an issue after merging #1329. Indeed, the shuffling can be point-wise evaluated, so we just need to ensure skipped epochs do not force recomputing the full shuffling. (In hindsight, this is a very sane property to have to mitigate other DoS vectors, e.g. related to evaluating the fork choice rule.) Now
|
You don't need to compute the entire shuffling to compute the proposer, you can just compute one single shuffled index (or sometimes a couple of extra shuffled indices if the first one doesn't work out). You can replace |
I understand that we don't need to do the entire shuffling, but don't we still need to scan the validator registry to find any validators that have activated/exited during the skipped epochs (in order to get the active validator indices, in order to do the point-wise shuffling)? This is the |
A few notes:
|
Thanks @JustinDrake, I'll come back to these notes if we decide to implement and store such a cache :) |
I'm pro adding the additional field. It takes ambiguity and complexity out of the equation and allows for a much simpler DoS protection and simpler evaluation when forwarding in the gossip protocol. This also lowers the overhead and simplifies the calcuation in processing proposer slashing |
How do we know if proposer with specified index is eligible to propose a block without processing registry updates for empty epochs? For instance, validator could be ejected due to its inactivity and wouldn't be included into a committee. |
You're right, and eligibility isn't just wrt activations/exits, it is wrt the shuffling in general. The "cheap" check of checking the proposer signature without knowing the shuffling opens ourselves up to a new DoS vector. Generally, there are only 64 valid proposers per epoch from the view of the canonical chain. If we require validation of the signature wrt the shuffling prior to forwarding a block, we get decent gossip DoS protection. If instead, we forward any block that has a valid proposer signature regardless of checking the shuffling, then we allow for the entirety of the validator set (minus the actual proposers) to get one free DoS block per epoch. A valid signature but unknown parent might enough to decide to perform the state transition but shouldn't be the min criterion to re-gossip the block. The decision on what to do with a block that is a child of a very old parent or an unknown parent still might need to be subject to heuristics (how old the parent, have we seen any attestations for the block, etc) |
Right. Checking a signature with no regard to a shuffling only checks data integrity and proof of possession of the public key. Also, there is pretty legal case when we have to do an epoch transition in order to validate block's signature:
Signature verification of block
Is there any cases when we want to continue building a chain upon a block that is behind last justified block? Proposer index in a block might aid in slashing condition checks. I.e. it should be easier to get proposer's identity and then proceed with that. |
The ability to do the cheap check reduces the actors that can request you to do an "expensive" check. There's almost no computational overhead to do the cheap check before you do the expensive one. |
Agree. That said, validator index is not a 100% reliable thing because it may change due to massive reorg in eth1 chain. And it could make blocks produced by a validator eventually invalid. Do we want to care about that in this particular case? |
Do we still want to add a
Feel free to reopen if you feel otherwise :) |
Problem
I've been thinking about a DoS vector for block processing at sigp/lighthouse#485 (comment).
In summary, a network participant can produce a block which has a parent block more than one epoch ago (e.g., the last finalized block). Before we can verify the signature of this new block, we need to compute the shuffling for the block's epoch where all slots between it and it's parent have been skipped.
Computing the shuffling that results from this large cross-epoch skip is roughly
O(V)
, whereV
is the validator count. (We might need to recompute the active validator set due to validators exiting or activating).This means that detecting if some block has been signed by a deposited (not necessarily active) validator is
O(V)
.To reduce our attack surface, I think it would be desirable to verify that a block has been produced by a deposited validator every time we receive a block from the network (given we're adequately synced). As such, if we're going to call this function a lot, it would be nice if it were faster and more
O(1)
.Potential Solution
It's difficult to build a cache for this operation because the attacker can modify the shuffling depending upon which parent block they choose. The number of caches required becomes prohibitive.
It seems that adding a
proposer
field to aBeaconBlock
(which holds the block proposer's validator index) would make this operationO(1)
at the cost of 8 bytes per block.I'm interested to hear thoughts or non-spec-changing alternatives :)
The text was updated successfully, but these errors were encountered: