Skip to content

Commit

Permalink
Merge pull request #2916 from etan-status/lc-forkversion
Browse files Browse the repository at this point in the history
  • Loading branch information
hwwhww authored Jun 27, 2022
2 parents d4a2bdc + 9a253e4 commit a40a644
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 19 deletions.
19 changes: 19 additions & 0 deletions specs/altair/fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

- [Introduction](#introduction)
- [Configuration](#configuration)
- [Helper functions](#helper-functions)
- [Misc](#misc)
- [`compute_fork_version`](#compute_fork_version)
- [Fork to Altair](#fork-to-altair)
- [Fork trigger](#fork-trigger)
- [Upgrading the state](#upgrading-the-state)
Expand All @@ -26,6 +29,22 @@ Warning: this configuration is not definitive.
| `ALTAIR_FORK_VERSION` | `Version('0x01000000')` |
| `ALTAIR_FORK_EPOCH` | `Epoch(74240)` (Oct 27, 2021, 10:56:23am UTC) |

## Helper functions

### Misc

#### `compute_fork_version`

```python
def compute_fork_version(epoch: Epoch) -> Version:
"""
Return the fork version at the given ``epoch``.
"""
if epoch >= ALTAIR_FORK_EPOCH:
return ALTAIR_FORK_VERSION
return GENESIS_FORK_VERSION
```

## Fork to Altair

### Fork trigger
Expand Down
5 changes: 2 additions & 3 deletions specs/altair/sync-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ class LightClientUpdate(Container):
finality_branch: Vector[Bytes32, floorlog2(FINALIZED_ROOT_INDEX)]
# Sync committee aggregate signature
sync_aggregate: SyncAggregate
# Fork version for the aggregate signature
fork_version: Version
# Slot at which the aggregate signature was created (untrusted)
signature_slot: Slot
```
Expand Down Expand Up @@ -211,7 +209,8 @@ def validate_light_client_update(store: LightClientStore,
pubkey for (bit, pubkey) in zip(sync_aggregate.sync_committee_bits, sync_committee.pubkeys)
if bit
]
domain = compute_domain(DOMAIN_SYNC_COMMITTEE, update.fork_version, genesis_validators_root)
fork_version = compute_fork_version(compute_epoch_at_slot(update.signature_slot))
domain = compute_domain(DOMAIN_SYNC_COMMITTEE, fork_version, genesis_validators_root)
signing_root = compute_signing_root(update.attested_header, domain)
assert bls.FastAggregateVerify(participant_pubkeys, signing_root, sync_aggregate.sync_committee_signature)
```
Expand Down
21 changes: 21 additions & 0 deletions specs/bellatrix/fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

- [Introduction](#introduction)
- [Configuration](#configuration)
- [Helper functions](#helper-functions)
- [Misc](#misc)
- [Modified `compute_fork_version`](#modified-compute_fork_version)
- [Fork to Bellatrix](#fork-to-bellatrix)
- [Fork trigger](#fork-trigger)
- [Upgrading the state](#upgrading-the-state)
Expand All @@ -28,6 +31,24 @@ Warning: this configuration is not definitive.
| `BELLATRIX_FORK_VERSION` | `Version('0x02000000')` |
| `BELLATRIX_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |

## Helper functions

### Misc

#### Modified `compute_fork_version`

```python
def compute_fork_version(epoch: Epoch) -> Version:
"""
Return the fork version at the given ``epoch``.
"""
if epoch >= BELLATRIX_FORK_EPOCH:
return BELLATRIX_FORK_VERSION
if epoch >= ALTAIR_FORK_EPOCH:
return ALTAIR_FORK_VERSION
return GENESIS_FORK_VERSION
```

## Fork to Bellatrix

### Fork trigger
Expand Down
23 changes: 23 additions & 0 deletions specs/capella/fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

- [Introduction](#introduction)
- [Configuration](#configuration)
- [Helper functions](#helper-functions)
- [Misc](#misc)
- [Modified `compute_fork_version`](#modified-compute_fork_version)
- [Fork to Capella](#fork-to-capella)
- [Fork trigger](#fork-trigger)
- [Upgrading the state](#upgrading-the-state)
Expand All @@ -27,6 +30,26 @@ Warning: this configuration is not definitive.
| `CAPELLA_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |


## Helper functions

### Misc

#### Modified `compute_fork_version`

```python
def compute_fork_version(epoch: Epoch) -> Version:
"""
Return the fork version at the given ``epoch``.
"""
if epoch >= CAPELLA_FORK_EPOCH:
return CAPELLA_FORK_VERSION
if epoch >= BELLATRIX_FORK_EPOCH:
return BELLATRIX_FORK_VERSION
if epoch >= ALTAIR_FORK_EPOCH:
return ALTAIR_FORK_VERSION
return GENESIS_FORK_VERSION
```

## Fork to Capella

### Fork trigger
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
from eth2spec.test.context import spec_configured_state_test, with_phases
from eth2spec.test.context import (
spec_configured_state_test,
spec_state_test_with_matching_config,
with_all_phases,
with_phases
)
from eth2spec.test.helpers.constants import ALTAIR


Expand All @@ -17,3 +22,28 @@ def test_config_override(spec, state):
# TODO: it would be nice if the create_genesis_state actually outputs a state
# for the fork with a slot that matches at least the fork boundary.
# assert spec.get_current_epoch(state) >= 4


@with_all_phases
@spec_state_test_with_matching_config
def test_override_config_fork_epoch(spec, state):
if state.fork.current_version == spec.config.GENESIS_FORK_VERSION:
return

assert spec.config.ALTAIR_FORK_EPOCH == spec.GENESIS_EPOCH
if state.fork.current_version == spec.config.ALTAIR_FORK_VERSION:
return

assert spec.config.BELLATRIX_FORK_EPOCH == spec.GENESIS_EPOCH
if state.fork.current_version == spec.config.BELLATRIX_FORK_VERSION:
return

assert spec.config.CAPELLA_FORK_EPOCH == spec.GENESIS_EPOCH
if state.fork.current_version == spec.config.CAPELLA_FORK_VERSION:
return

assert spec.config.SHARDING_FORK_EPOCH == spec.GENESIS_EPOCH
if state.fork.current_version == spec.config.SHARDING_FORK_VERSION:
return

assert False # Fork is missing
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from copy import deepcopy

from eth2spec.test.context import (
spec_state_test,
spec_state_test_with_matching_config,
with_presets,
with_altair_and_later,
)
Expand All @@ -25,7 +25,7 @@


@with_altair_and_later
@spec_state_test
@spec_state_test_with_matching_config
def test_process_light_client_update_not_timeout(spec, state):
store = initialize_light_client_store(spec, state)

Expand All @@ -41,7 +41,7 @@ def test_process_light_client_update_not_timeout(spec, state):
)

# Sync committee signing the block_header
sync_aggregate, fork_version, signature_slot = get_sync_aggregate(spec, state, block_header)
sync_aggregate, signature_slot = get_sync_aggregate(spec, state, block_header)
next_sync_committee_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.NEXT_SYNC_COMMITTEE_INDEX))]

# Ensure that finality checkpoint is genesis
Expand All @@ -57,7 +57,6 @@ def test_process_light_client_update_not_timeout(spec, state):
finalized_header=finality_header,
finality_branch=finality_branch,
sync_aggregate=sync_aggregate,
fork_version=fork_version,
signature_slot=signature_slot,
)

Expand All @@ -72,7 +71,7 @@ def test_process_light_client_update_not_timeout(spec, state):


@with_altair_and_later
@spec_state_test
@spec_state_test_with_matching_config
@with_presets([MINIMAL], reason="too slow")
def test_process_light_client_update_at_period_boundary(spec, state):
store = initialize_light_client_store(spec, state)
Expand All @@ -94,7 +93,7 @@ def test_process_light_client_update_at_period_boundary(spec, state):
)

# Sync committee signing the block_header
sync_aggregate, fork_version, signature_slot = get_sync_aggregate(spec, state, block_header)
sync_aggregate, signature_slot = get_sync_aggregate(spec, state, block_header)
next_sync_committee_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.NEXT_SYNC_COMMITTEE_INDEX))]

# Finality is unchanged
Expand All @@ -108,7 +107,6 @@ def test_process_light_client_update_at_period_boundary(spec, state):
finalized_header=finality_header,
finality_branch=finality_branch,
sync_aggregate=sync_aggregate,
fork_version=fork_version,
signature_slot=signature_slot,
)

Expand All @@ -123,7 +121,7 @@ def test_process_light_client_update_at_period_boundary(spec, state):


@with_altair_and_later
@spec_state_test
@spec_state_test_with_matching_config
@with_presets([MINIMAL], reason="too slow")
def test_process_light_client_update_timeout(spec, state):
store = initialize_light_client_store(spec, state)
Expand All @@ -145,7 +143,7 @@ def test_process_light_client_update_timeout(spec, state):
)

# Sync committee signing the block_header
sync_aggregate, fork_version, signature_slot = get_sync_aggregate(spec, state, block_header)
sync_aggregate, signature_slot = get_sync_aggregate(spec, state, block_header)

# Sync committee is updated
next_sync_committee_branch = build_proof(state.get_backing(), spec.NEXT_SYNC_COMMITTEE_INDEX)
Expand All @@ -160,7 +158,6 @@ def test_process_light_client_update_timeout(spec, state):
finalized_header=finality_header,
finality_branch=finality_branch,
sync_aggregate=sync_aggregate,
fork_version=fork_version,
signature_slot=signature_slot,
)

Expand All @@ -175,7 +172,7 @@ def test_process_light_client_update_timeout(spec, state):


@with_altair_and_later
@spec_state_test
@spec_state_test_with_matching_config
@with_presets([MINIMAL], reason="too slow")
def test_process_light_client_update_finality_updated(spec, state):
store = initialize_light_client_store(spec, state)
Expand Down Expand Up @@ -211,7 +208,7 @@ def test_process_light_client_update_finality_updated(spec, state):
)

# Sync committee signing the block_header
sync_aggregate, fork_version, signature_slot = get_sync_aggregate(spec, state, block_header)
sync_aggregate, signature_slot = get_sync_aggregate(spec, state, block_header)

update = spec.LightClientUpdate(
attested_header=block_header,
Expand All @@ -220,7 +217,6 @@ def test_process_light_client_update_finality_updated(spec, state):
finalized_header=finalized_block_header,
finality_branch=finality_branch,
sync_aggregate=sync_aggregate,
fork_version=fork_version,
signature_slot=signature_slot,
)

Expand Down
33 changes: 33 additions & 0 deletions tests/core/pyspec/eth2spec/test/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,39 @@ def decorator(fn):
return decorator


def config_fork_epoch_overrides(spec, state):
overrides = {}
if state.fork.current_version == spec.config.GENESIS_FORK_VERSION:
pass
elif state.fork.current_version == spec.config.ALTAIR_FORK_VERSION:
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH
elif state.fork.current_version == spec.config.BELLATRIX_FORK_VERSION:
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['BELLATRIX_FORK_EPOCH'] = spec.GENESIS_EPOCH
elif state.fork.current_version == spec.config.CAPELLA_FORK_VERSION:
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['BELLATRIX_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['CAPELLA_FORK_EPOCH'] = spec.GENESIS_EPOCH
elif state.fork.current_version == spec.config.SHARDING_FORK_VERSION:
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['BELLATRIX_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['CAPELLA_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['SHARDING_FORK_EPOCH'] = spec.GENESIS_EPOCH
else:
assert False # Fork is missing
return overrides


def spec_state_test_with_matching_config(fn):
def decorator(fn):
def wrapper(*args, spec: Spec, **kw):
conf = config_fork_epoch_overrides(spec, kw['state'])
overrides = with_config_overrides(conf)
return overrides(fn)(*args, spec=spec, **kw)
return wrapper
return spec_test(with_state(decorator(single_phase(fn))))


def expect_assertion_error(fn):
bad = False
try:
Expand Down
3 changes: 1 addition & 2 deletions tests/core/pyspec/eth2spec/test/helpers/light_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,4 @@ def get_sync_aggregate(spec, state, block_header, signature_slot=None):
sync_committee_bits=sync_committee_bits,
sync_committee_signature=sync_committee_signature,
)
fork_version = signature_state.fork.current_version
return sync_aggregate, fork_version, signature_slot
return sync_aggregate, signature_slot

0 comments on commit a40a644

Please sign in to comment.