-
Notifications
You must be signed in to change notification settings - Fork 973
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
Problems with attestations from incompatible forks #1456
Comments
A fork should not change the validity of attestations before the fork start, unless that's the intention of the fork. I don't think the states will be incompatible; ensuring the active validators are the same across a fork version is part of forking, similar to the seed look-ahead, it's part of knowing what to validate before it's too late to do anything. If a fork would change the active validators or the shuffling etc., it should do so only after a look-ahead period has passed since the new rules are applied.
Are we talking about a fork induced difference here? If so, the sig validation cannot succeed, since you sign with the fork version in the signature domain (== domain type concatenated with fork version) |
The issue is not about manual forks, but about the forks in the sense of the fork-choice spec, i.e. situations where a block has two or more immediate descendants. |
Ah I see. For slashings attestation checking is not as strictly coupled; validator indices are embedded in the slashing itself, so there is no dependency on the exact state of the chain. For normal attestations, they would only be included if their scope is part of the chain (and at that point you have consistency and are just dealing with fork versions). So I don't see what edge case you need inclusion of attestations from different forks for. |
One problem is that in some cases such an attestation can still pass signature check and be included in a block. The second thing is to make implementers aware of such cases so that they be more careful when validating attestations. |
@protolambda @ericsson49 What is the outcome of this discussion? Do we want to make a change in phase 0? |
I think this is the most confusing part. I don't see others having problems with the way attestations are currently processed, and was assuming this issue was already solved offline. Anyway, ping @ericsson49 if there is a concrete implementation problem, otherwise I think we can close this issue. |
The idea has been to forbid inclusion of attestations from such incompatible forks on the spec level, so that implementations handle it uniformly. |
Attester and proposer roles assignment are determined by a shuffling of a set of active validators, which depends on a seed. The seed and the set of active validators, in their turn, are detemined by a chain of blocks (randao, slashings, deposits, exits, etc). An attestation data doesn't contain indices of a block proposer and attesters in an explicit form, they are (re)calculated based on a state and aggregation_bits.
That means it's important that a state that is used to restore attester and proposer indices contain the right seed and the right set of active validators. If it doesn't hold, then it can lead to problems (described later).
When an attestation is created or consumed/processed, the reference states (used to calculate proposer/attesters for the attestation's slot) will be different. However, that doesn't necessarily mean the seed and the set of active validators will differ too. As proposer and attester assignment for an epoch are determined at the beginning of the previous epoch, some beacon states can lead to the same assignments. Let's call such states compatible.
For example, when an attester creates an attestation, the reference state is the head state (with slot transitions applied up to the current slot). When an attestation is used in a fork choice, the reference state is the state at the beginning of the target epoch. When an attestation is to be included in a block or is processed as a part of a block, the reference state is the state of the block's parent with slot transitions applied. So, in general, the states can be incompatible between each other, i.e. having different seeds and/or sets of active validators. And thus leading to incorrect reconstruction of attester and proposer indices.
Such incompatibility can arise when there has been a fork and an attestation referencing one branch of the fork is inculded in a block from another branch of the fork. If the fork happend in an epoch before the previous epoch, then it's enough time that differences in block chains start to affect shufflings.
Potential problems:
So, in order to prevent such problems we suggest that only attestations from compatible states can be included in blocks. And the appropriate check should be implemented as a part of process_attestation method (and/or get_indexed_attestation method). Most likely such attestations cannot be included anyway, but when they can it leads to a covert problem (wrong proposer index in a pending attestation).
The text was updated successfully, but these errors were encountered: