From 7f8858b2ac4641a98539cd50ab942e3ce159d2dc Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 5 Jan 2024 18:43:37 +0800 Subject: [PATCH] Add `PeerDAS` feature --- .gitignore | 1 + Makefile | 2 +- configs/mainnet.yaml | 4 + configs/minimal.yaml | 4 + pysetup/constants.py | 1 + pysetup/md_doc_paths.py | 2 + pysetup/spec_builders/__init__.py | 3 +- pysetup/spec_builders/peerdas.py | 14 ++ specs/_features/peerdas/fork.md | 125 ++++++++++++++++++ .../polynomial-commitments-sampling.md | 0 .../pyspec/eth2spec/test/helpers/constants.py | 3 + 11 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 pysetup/spec_builders/peerdas.py create mode 100644 specs/_features/peerdas/fork.md rename specs/{deneb => _features/peerdas}/polynomial-commitments-sampling.md (100%) diff --git a/.gitignore b/.gitignore index e88207dd7..b9a7b5ff3 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ tests/core/pyspec/eth2spec/deneb/ tests/core/pyspec/eth2spec/eip6110/ tests/core/pyspec/eth2spec/eip7002/ tests/core/pyspec/eth2spec/whisk/ +tests/core/pyspec/eth2spec/peerdas/ # coverage reports .htmlcov diff --git a/Makefile b/Makefile index d0d750e89..2003c5df5 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ MARKDOWN_FILES = $(wildcard $(SPEC_DIR)/*/*.md) \ $(wildcard $(SPEC_DIR)/_features/*/*/*.md) \ $(wildcard $(SSZ_DIR)/*.md) -ALL_EXECUTABLE_SPEC_NAMES = phase0 altair bellatrix capella deneb eip6110 eip7002 whisk +ALL_EXECUTABLE_SPEC_NAMES = phase0 altair bellatrix capella deneb eip6110 eip7002 whisk peerdas # The parameters for commands. Use `foreach` to avoid listing specs again. COVERAGE_SCOPE := $(foreach S,$(ALL_EXECUTABLE_SPEC_NAMES), --cov=eth2spec.$S.$(TEST_PRESET_TYPE)) PYLINT_SCOPE := $(foreach S,$(ALL_EXECUTABLE_SPEC_NAMES), ./eth2spec/$S) diff --git a/configs/mainnet.yaml b/configs/mainnet.yaml index e0f9128b7..3202af703 100644 --- a/configs/mainnet.yaml +++ b/configs/mainnet.yaml @@ -154,3 +154,7 @@ BLOB_SIDECAR_SUBNET_COUNT: 6 WHISK_EPOCHS_PER_SHUFFLING_PHASE: 256 # `Epoch(2)` WHISK_PROPOSER_SELECTION_GAP: 2 + +# PEERDAS +PEERDAS_FORK_VERSION: 0x06000001 +PEERDAS_FORK_EPOCH: 18446744073709551615 diff --git a/configs/minimal.yaml b/configs/minimal.yaml index cdfbca3a2..eec2cde6e 100644 --- a/configs/minimal.yaml +++ b/configs/minimal.yaml @@ -153,3 +153,7 @@ BLOB_SIDECAR_SUBNET_COUNT: 6 # Whisk WHISK_EPOCHS_PER_SHUFFLING_PHASE: 4 WHISK_PROPOSER_SELECTION_GAP: 1 + +# PEERDAS +PEERDAS_FORK_VERSION: 0x06000001 +PEERDAS_FORK_EPOCH: 18446744073709551615 diff --git a/pysetup/constants.py b/pysetup/constants.py index 8d5345563..7f1d6dcdc 100644 --- a/pysetup/constants.py +++ b/pysetup/constants.py @@ -7,6 +7,7 @@ DENEB = 'deneb' EIP6110 = 'eip6110' EIP7002 = 'eip7002' WHISK = 'whisk' +PEERDAS = 'peerdas' diff --git a/pysetup/md_doc_paths.py b/pysetup/md_doc_paths.py index 781ae41db..24621aac3 100644 --- a/pysetup/md_doc_paths.py +++ b/pysetup/md_doc_paths.py @@ -9,6 +9,7 @@ from .constants import ( EIP6110, WHISK, EIP7002, + PEERDAS, ) @@ -21,6 +22,7 @@ PREVIOUS_FORK_OF = { EIP6110: DENEB, WHISK: CAPELLA, EIP7002: CAPELLA, + PEERDAS: DENEB, } ALL_FORKS = list(PREVIOUS_FORK_OF.keys()) diff --git a/pysetup/spec_builders/__init__.py b/pysetup/spec_builders/__init__.py index 794ae50d2..745010d0c 100644 --- a/pysetup/spec_builders/__init__.py +++ b/pysetup/spec_builders/__init__.py @@ -6,12 +6,13 @@ from .deneb import DenebSpecBuilder from .eip6110 import EIP6110SpecBuilder from .eip7002 import EIP7002SpecBuilder from .whisk import WhiskSpecBuilder +from .peerdas import PeerDASSpecBuilder spec_builders = { builder.fork: builder for builder in ( Phase0SpecBuilder, AltairSpecBuilder, BellatrixSpecBuilder, CapellaSpecBuilder, DenebSpecBuilder, - EIP6110SpecBuilder, EIP7002SpecBuilder, WhiskSpecBuilder, + EIP6110SpecBuilder, EIP7002SpecBuilder, WhiskSpecBuilder, PeerDASSpecBuilder, ) } diff --git a/pysetup/spec_builders/peerdas.py b/pysetup/spec_builders/peerdas.py new file mode 100644 index 000000000..0d72976e2 --- /dev/null +++ b/pysetup/spec_builders/peerdas.py @@ -0,0 +1,14 @@ +from typing import Dict + +from .base import BaseSpecBuilder +from ..constants import PEERDAS + + +class PeerDASSpecBuilder(BaseSpecBuilder): + fork: str = PEERDAS + + @classmethod + def imports(cls, preset_name: str): + return f''' +from eth2spec.deneb import {preset_name} as deneb +''' diff --git a/specs/_features/peerdas/fork.md b/specs/_features/peerdas/fork.md new file mode 100644 index 000000000..e0991c0f9 --- /dev/null +++ b/specs/_features/peerdas/fork.md @@ -0,0 +1,125 @@ +# PeerDAS -- Fork Logic + +**Notice**: This document is a work-in-progress for researchers and implementers. + +## Table of contents + + + + +- [Introduction](#introduction) +- [Configuration](#configuration) +- [Helper functions](#helper-functions) + - [Misc](#misc) + - [Modified `compute_fork_version`](#modified-compute_fork_version) +- [Fork to PeerDAS](#fork-to-peerdas) + - [Fork trigger](#fork-trigger) + - [Upgrading the state](#upgrading-the-state) + + + +## Introduction + +This document describes the process of PeerDAS upgrade. + +## Configuration + +Warning: this configuration is not definitive. + +| Name | Value | +| - | - | +| `PEERDAS_FORK_VERSION` | `Version('0x05000000')` | +| `PEERDAS_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 >= PEERDAS_FORK_EPOCH: + return PEERDAS_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 PeerDAS + +### Fork trigger + +PeerDAS does not need a hard fork. We only add this fork doc for compiling this new feature in pyspec. + +For now, we assume the condition will be triggered at epoch `PEERDAS_FORK_EPOCH`. + +Note that for the pure PeerDAS networks, we don't apply `upgrade_to_peerdas` since it starts with PeerDAS version logic. + +### Upgrading the state + +If `state.slot % SLOTS_PER_EPOCH == 0` and `compute_epoch_at_slot(state.slot) == PEERDAS_FORK_EPOCH`, +an irregular state change is made to upgrade to PeerDAS. + +```python +def upgrade_to_peerdas(pre: deneb.BeaconState) -> BeaconState: + epoch = deneb.get_current_epoch(pre) + 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=PEERDAS_FORK_VERSION, # [Modified in PeerDAS] + epoch=epoch, + ), + # 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 +``` diff --git a/specs/deneb/polynomial-commitments-sampling.md b/specs/_features/peerdas/polynomial-commitments-sampling.md similarity index 100% rename from specs/deneb/polynomial-commitments-sampling.md rename to specs/_features/peerdas/polynomial-commitments-sampling.md diff --git a/tests/core/pyspec/eth2spec/test/helpers/constants.py b/tests/core/pyspec/eth2spec/test/helpers/constants.py index 2d1b4a821..a79feb96e 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/constants.py +++ b/tests/core/pyspec/eth2spec/test/helpers/constants.py @@ -19,6 +19,7 @@ DAS = SpecForkName('das') EIP6110 = SpecForkName('eip6110') EIP7002 = SpecForkName('eip7002') WHISK = SpecForkName('whisk') +PEERDAS = SpecForkName('peerdas') # # SpecFork settings @@ -37,6 +38,7 @@ ALL_PHASES = ( # Experimental patches EIP6110, EIP7002, + PEERDAS, ) # The forks that have light client specs LIGHT_CLIENT_TESTING_FORKS = (*[item for item in MAINNET_FORKS if item != PHASE0], DENEB) @@ -57,6 +59,7 @@ PREVIOUS_FORK_OF = { EIP6110: DENEB, WHISK: CAPELLA, EIP7002: CAPELLA, + PEERDAS: DENEB, } # For fork transition tests