ethereum / ethereum/consensus-specs
Multiple fork transitions on same slot/epoch discard old `fork_version`s
- Dominant language
- Python
- Stars
- 4k
- Forks
- 1.3k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 58
Description
The result is that certain messages across multiple-fork-transition-per-epoch boundaries might not be verifiable when received.
https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/fork.md#upgrading-the-state states that the fork of the upgraded state is
```python
fork=Fork(
previous_version=pre.fork.current_version,
current_version=ALTAIR_FORK_VERSION,
epoch=epoch,
),
```
https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/fork.md#upgrading-the-state states that for Bellatrix, it's:
```python
fork=Fork(
previous_version=pre.fork.current_version,
current_version=BELLATRIX_FORK_VERSION,
epoch=epoch,
),
```
And for https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/fork.md#upgrading-the-state, it's
```python
fork=Fork(
previous_version=pre.fork.current_version,
current_version=CAPELLA_FORK_VERSION,
epoch=epoch,
),
```
That is, even if there was no observable beacon chain-time during which an `ALTAIR_FORK_EPOCH == BELLATRIX_FORK_EPOCH` or `BELLATRIX_FORK_EPOCH == CAPELLA_FORK_EPOCH` network existed in that intermediate fork, it will still show up as `state.fork.previous_version` of the fork to which it was upgraded, not necessarily the chronologically previous fork in question (e.g., the fork which might appear in the beacon API fork schedule).
This means that signatures of attestations, for example, from a slot or two before an `ALTAIR_FORK_EPOCH == BELLATRIX_FORK_EPOCH` or `BELLATRIX_FORK_EPOCH == CAPELLA_FORK_EPOCH` transition and then included in slots (which is supposed to be valid for up to 32 slots) cannot be verified afterward by a conforming client using https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#get_domain as written:
```python
def get_domain(state: BeaconState, domain_type: DomainType, epoch: Epoch=None) -> Domain:
...
fork_version = state.fork.previous_version if epoch < state.fork.epoch else state.fork.current_version
...
```
because `fork_version` cannot access an old enough version in `state` by then.
When fork transitions only occur on successive epochs, the attestations which trigger this are old enough to be invalid (`ATTESTATION_PROPAGATION_SLOT_RANGE == 32`), but in either the `minimal` preset or immediately-after-each-other fork transitions, there can be glitches around these fork boundaries.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.