Skip to content

Commit

Permalink
working through att slot range fix
Browse files Browse the repository at this point in the history
  • Loading branch information
djrtwo committed May 15, 2023
1 parent f7352d1 commit 786ccbe
Show file tree
Hide file tree
Showing 12 changed files with 271 additions and 13 deletions.
14 changes: 14 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,20 @@ jobs:
command: make citest fork=eip6110
- store_test_results:
path: tests/core/pyspec/test-reports
test-attslotrange:
docker:
- image: circleci/python:3.8
working_directory: ~/specs-repo
steps:
- restore_cache:
key: v3-specs-repo-{{ .Branch }}-{{ .Revision }}
- restore_pyspec_cached_venv
- run:
name: Run py-tests
command: make citest fork=attslotrange
- store_test_results:
path: tests/core/pyspec/test-reports

table_of_contents:
docker:
- image: circleci/node:10.16.3
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ tests/core/pyspec/eth2spec/bellatrix/
tests/core/pyspec/eth2spec/capella/
tests/core/pyspec/eth2spec/deneb/
tests/core/pyspec/eth2spec/eip6110/
tests/core/pyspec/eth2spec/attslotrange/

# coverage reports
.htmlcov
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ MARKDOWN_FILES = $(wildcard $(SPEC_DIR)/*/*.md) \
$(wildcard $(SPEC_DIR)/_features/*/*/*.md) \
$(wildcard $(SSZ_DIR)/*.md)

ALL_EXECUTABLE_SPECS = phase0 altair bellatrix capella deneb eip6110
ALL_EXECUTABLE_SPECS = phase0 altair bellatrix capella deneb eip6110 attslotrange
# The parameters for commands. Use `foreach` to avoid listing specs again.
COVERAGE_SCOPE := $(foreach S,$(ALL_EXECUTABLE_SPECS), --cov=eth2spec.$S.$(TEST_PRESET_TYPE))
PYLINT_SCOPE := $(foreach S,$(ALL_EXECUTABLE_SPECS), ./eth2spec/$S)
Expand Down
3 changes: 3 additions & 0 deletions configs/mainnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ DENEB_FORK_EPOCH: 18446744073709551615
# EIP6110
EIP6110_FORK_VERSION: 0x05000000 # temporary stub
EIP6110_FORK_EPOCH: 18446744073709551615
# AttSlotRange
ATTSLOTRANGE_FORK_VERSION: 0x05000000 # temporary stub
ATTSLOTRANGE_FORK_EPOCH: 18446744073709551615


# Time parameters
Expand Down
5 changes: 5 additions & 0 deletions configs/minimal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ DENEB_FORK_EPOCH: 18446744073709551615
# EIP6110
EIP6110_FORK_VERSION: 0x05000001
EIP6110_FORK_EPOCH: 18446744073709551615
# AttSlotRange
ATTSLOTRANGE_FORK_VERSION: 0x05000001
ATTSLOTRANGE_FORK_EPOCH: 18446744073709551615




# Time parameters
Expand Down
37 changes: 28 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def installPackage(package: str):
CAPELLA = 'capella'
DENEB = 'deneb'
EIP6110 = 'eip6110'
ATTSLOTRANGE= 'attslotrange'


# The helper functions that are used when defining constants
Expand Down Expand Up @@ -680,11 +681,23 @@ def imports(cls, preset_name: str):
from eth2spec.deneb import {preset_name} as deneb
'''

#
# AttSlotRangeSpecBuilder
#
class AttSlotRangeSpecBuilder(DenebSpecBuilder):
fork: str = ATTSLOTRANGE

spec_builders = {
builder.fork: builder
for builder in (Phase0SpecBuilder, AltairSpecBuilder, BellatrixSpecBuilder, CapellaSpecBuilder, DenebSpecBuilder, EIP6110SpecBuilder)
}
@classmethod
def imports(cls, preset_name: str):
return super().imports(preset_name) + f'''
from eth2spec.deneb import {preset_name} as deneb
'''

all_builders = (
Phase0SpecBuilder, AltairSpecBuilder, BellatrixSpecBuilder, CapellaSpecBuilder, DenebSpecBuilder,
EIP6110SpecBuilder, AttSlotRangeSpecBuilder,
)
spec_builders = {builder.fork: builder for builder in all_builders}


def is_byte_vector(value: str) -> bool:
Expand Down Expand Up @@ -982,14 +995,14 @@ def finalize_options(self):
if len(self.md_doc_paths) == 0:
print("no paths were specified, using default markdown file paths for pyspec"
" build (spec fork: %s)" % self.spec_fork)
if self.spec_fork in (PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, EIP6110):
if self.spec_fork in (PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, EIP6110, ATTSLOTRANGE):
self.md_doc_paths = """
specs/phase0/beacon-chain.md
specs/phase0/fork-choice.md
specs/phase0/validator.md
specs/phase0/weak-subjectivity.md
"""
if self.spec_fork in (ALTAIR, BELLATRIX, CAPELLA, DENEB, EIP6110):
if self.spec_fork in (ALTAIR, BELLATRIX, CAPELLA, DENEB, EIP6110, ATTSLOTRANGE):
self.md_doc_paths += """
specs/altair/light-client/full-node.md
specs/altair/light-client/light-client.md
Expand All @@ -1001,7 +1014,7 @@ def finalize_options(self):
specs/altair/validator.md
specs/altair/p2p-interface.md
"""
if self.spec_fork in (BELLATRIX, CAPELLA, DENEB, EIP6110):
if self.spec_fork in (BELLATRIX, CAPELLA, DENEB, EIP6110, ATTSLOTRANGE):
self.md_doc_paths += """
specs/bellatrix/beacon-chain.md
specs/bellatrix/fork.md
Expand All @@ -1010,7 +1023,7 @@ def finalize_options(self):
specs/bellatrix/p2p-interface.md
sync/optimistic.md
"""
if self.spec_fork in (CAPELLA, DENEB, EIP6110):
if self.spec_fork in (CAPELLA, DENEB, EIP6110, ATTSLOTRANGE):
self.md_doc_paths += """
specs/capella/light-client/fork.md
specs/capella/light-client/full-node.md
Expand All @@ -1022,7 +1035,7 @@ def finalize_options(self):
specs/capella/validator.md
specs/capella/p2p-interface.md
"""
if self.spec_fork in (DENEB, EIP6110):
if self.spec_fork in (DENEB, EIP6110, ATTSLOTRANGE):
self.md_doc_paths += """
specs/deneb/light-client/fork.md
specs/deneb/light-client/full-node.md
Expand All @@ -1044,6 +1057,12 @@ def finalize_options(self):
specs/_features/eip6110/beacon-chain.md
specs/_features/eip6110/fork.md
"""
if self.spec_fork == ATTSLOTRANGE:
self.md_doc_paths += """
specs/_features/attslotrange/beacon-chain.md
specs/_features/attslotrange/fork.md
"""

if len(self.md_doc_paths) == 0:
raise Exception('no markdown files specified, and spec fork "%s" is unknown', self.spec_fork)

Expand Down
74 changes: 74 additions & 0 deletions specs/_features/attslotrange/beacon-chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Deneb -- The Beacon Chain

**Notice**: This document is a work-in-progress for researchers and implementers.

## Table of contents

<!-- TOC -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Introduction](#introduction)
- [Preset](#preset)
- [Configuration](#configuration)
- [Containers](#containers)
- [Beacon chain state transition function](#beacon-chain-state-transition-function)
- [Block processing](#block-processing)
- [Modified `process_attestation`](#modified-process_attestation)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->

## Introduction

This feature allows for inclusion of attestations created during epoch `N` to be included in slots from epoch `N` as well as all slots in epoch `N+1` rather than the current `SLOTS_PER_EPOCH` slot restricted range. This is an extension of the Deneb upgrade.

## Preset

## Configuration

## Containers

## Beacon chain state transition function

### Block processing

#### Modified `process_attestation`

*Note*: The function `process_attestation` is modified to expand valid slots for inclusion tothose in the `target.epoch` epoch as well as those in the `target.epoch + 1` epoch.

```python
def process_attestation(state: BeaconState, attestation: Attestation) -> None:
data = attestation.data
assert data.target.epoch in (get_previous_epoch(state), get_current_epoch(state))
assert data.target.epoch == compute_epoch_at_slot(data.slot)
assert data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot # [Modified in AttSlotRange]
assert data.index < get_committee_count_per_slot(state, data.target.epoch)

committee = get_beacon_committee(state, data.slot, data.index)
assert len(attestation.aggregation_bits) == len(committee)

# Participation flag indices
participation_flag_indices = get_attestation_participation_flag_indices(state, data, state.slot - data.slot)

# Verify signature
assert is_valid_indexed_attestation(state, get_indexed_attestation(state, attestation))

# Update epoch participation flags
if data.target.epoch == get_current_epoch(state):
epoch_participation = state.current_epoch_participation
else:
epoch_participation = state.previous_epoch_participation

proposer_reward_numerator = 0
for index in get_attesting_indices(state, data, attestation.aggregation_bits):
for flag_index, weight in enumerate(PARTICIPATION_FLAG_WEIGHTS):
if flag_index in participation_flag_indices and not has_flag(epoch_participation[index], flag_index):
epoch_participation[index] = add_flag(epoch_participation[index], flag_index)
proposer_reward_numerator += get_base_reward(state, index) * weight

# Reward proposer
proposer_reward_denominator = (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT) * WEIGHT_DENOMINATOR // PROPOSER_WEIGHT
proposer_reward = Gwei(proposer_reward_numerator // proposer_reward_denominator)
increase_balance(state, get_beacon_proposer_index(state), proposer_reward)
```
123 changes: 123 additions & 0 deletions specs/_features/attslotrange/fork.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Att-Slot-Range -- Fork Logic

**Notice**: This document is a work-in-progress for researchers and implementers.

## Table of contents

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Introduction](#introduction)
- [Configuration](#configuration)
- [Helper functions](#helper-functions)
- [Misc](#misc)
- [Modified `compute_fork_version`](#modified-compute_fork_version)
- [Fork to EIP-6110](#fork-to-eip-6110)
- [Fork trigger](#fork-trigger)
- [Upgrading the state](#upgrading-the-state)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Introduction

This document describes the process of Att-Slot-Range upgrade.

## Configuration

Warning: this configuration is not definitive.

| Name | Value |
| - | - |
| `ATTSLOTRANGE_FORK_VERSION` | `Version('0x05000000')` |
| `ATTSLOTRANGE_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 >= ATTSLOTRANGE_FORK_EPOCH:
return ATTSLOTRANGE_FORK_VERSION
if epoch >= DENEB_FORK_EPOCH:
return DENEB_FORK_VERSION
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 AttSlotRange

### Fork trigger

TBD. This fork is defined for testing purposes, the EIP may be combined with other consensus-layer upgrade.
For now, we assume the condition will be triggered at epoch `ATTSLOTRANGE_FORK_EPOCH`.

Note that for the pure AttSlotRange networks, we don't apply `upgrade_to_attslotrange` since it starts with AttSlotRange version logic.

### Upgrading the state

If `state.slot % SLOTS_PER_EPOCH == 0` and `compute_epoch_at_slot(state.slot) == ATTSLOTRANGE_FORK_EPOCH,
an irregular state change is made to upgrade to AttSlotRange.

```python
def upgrade_to_attslotrange(pre: deneb.BeaconState) -> BeaconState:
post = BeaconState(
# Versioning
genesis_time=pre.genesis_time,
genesis_validators_root=pre.genesis_validators_root,
slot=pre.slot,
fork=Fork(
previous_version=pre.fork.current_version,
current_version=ATTSLOTRANGE_FORK_VERSION, # [Modified in Att-Slot-Range]
epoch=deneb.get_current_epoch(pre),
),
# History
latest_block_header=pre.latest_block_header,
block_roots=pre.block_roots,
state_roots=pre.state_roots,
historical_roots=pre.historical_roots,
# Eth1
eth1_data=pre.eth1_data,
eth1_data_votes=pre.eth1_data_votes,
eth1_deposit_index=pre.eth1_deposit_index,
# Registry
validators=pre.validators,
balances=pre.balances,
# Randomness
randao_mixes=pre.randao_mixes,
# Slashings
slashings=pre.slashings,
# Participation
previous_epoch_participation=pre.previous_epoch_participation,
current_epoch_participation=pre.current_epoch_participation,
# Finality
justification_bits=pre.justification_bits,
previous_justified_checkpoint=pre.previous_justified_checkpoint,
current_justified_checkpoint=pre.current_justified_checkpoint,
finalized_checkpoint=pre.finalized_checkpoint,
# Inactivity
inactivity_scores=pre.inactivity_scores,
# Sync
current_sync_committee=pre.current_sync_committee,
next_sync_committee=pre.next_sync_committee,
# Execution-layer
latest_execution_payload_header=pre.latest_execution_payload_header,
# Withdrawals
next_withdrawal_index=pre.next_withdrawal_index,
next_withdrawal_validator_index=pre.next_withdrawal_validator_index,
# Deep history valid from Capella onwards
historical_summaries=pre.historical_summaries,
)

return post
```
6 changes: 5 additions & 1 deletion tests/core/pyspec/eth2spec/test/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
from eth2spec.capella import mainnet as spec_capella_mainnet, minimal as spec_capella_minimal
from eth2spec.deneb import mainnet as spec_deneb_mainnet, minimal as spec_deneb_minimal
from eth2spec.eip6110 import mainnet as spec_eip6110_mainnet, minimal as spec_eip6110_minimal
from eth2spec.attslotrange import mainnet as spec_attslotrange_mainnet, minimal as spec_attslotrange_minimal
from eth2spec.utils import bls

from .exceptions import SkippedTest
from .helpers.constants import (
PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB,
EIP6110,
EIP6110, ATTSLOTRANGE,
MINIMAL, MAINNET,
ALL_PHASES,
ALL_FORK_UPGRADES,
Expand Down Expand Up @@ -82,6 +83,7 @@ class ForkMeta:
CAPELLA: spec_capella_minimal,
DENEB: spec_deneb_minimal,
EIP6110: spec_eip6110_minimal,
ATTSLOTRANGE: spec_attslotrange_minimal,
},
MAINNET: {
PHASE0: spec_phase0_mainnet,
Expand All @@ -90,6 +92,7 @@ class ForkMeta:
CAPELLA: spec_capella_mainnet,
DENEB: spec_deneb_mainnet,
EIP6110: spec_eip6110_mainnet,
ATTSLOTRANGE: spec_attslotrange_mainnet,
},
}

Expand Down Expand Up @@ -433,6 +436,7 @@ def decorator(fn):
with_capella_and_later = with_all_phases_from(CAPELLA)
with_deneb_and_later = with_all_phases_from(DENEB)
with_eip6110_and_later = with_all_phases_from(EIP6110)
with_attslotrange_and_later = with_all_phases_from(ATTSLOTRANGE)


def _get_preset_targets(kw):
Expand Down
Loading

0 comments on commit 786ccbe

Please sign in to comment.