Add EIP-7251 to Electra fork

This commit is contained in:
Alex Stokes 2024-04-09 12:49:58 -06:00
parent 77ec547cc7
commit ce3931653d
No known key found for this signature in database
29 changed files with 1723 additions and 400 deletions

1
.gitignore vendored
View File

@ -23,7 +23,6 @@ tests/core/pyspec/eth2spec/capella/
tests/core/pyspec/eth2spec/deneb/ tests/core/pyspec/eth2spec/deneb/
tests/core/pyspec/eth2spec/electra/ tests/core/pyspec/eth2spec/electra/
tests/core/pyspec/eth2spec/whisk/ tests/core/pyspec/eth2spec/whisk/
tests/core/pyspec/eth2spec/eip7251/
tests/core/pyspec/eth2spec/eip7594/ tests/core/pyspec/eth2spec/eip7594/
# coverage reports # coverage reports

View File

@ -53,9 +53,6 @@ DENEB_FORK_EPOCH: 269568 # March 13, 2024, 01:55:35pm UTC
# Electra # Electra
ELECTRA_FORK_VERSION: 0x05000000 ELECTRA_FORK_VERSION: 0x05000000
ELECTRA_FORK_EPOCH: 18446744073709551615 ELECTRA_FORK_EPOCH: 18446744073709551615
# EIP7251
EIP7251_FORK_VERSION: 0x06000000 # temporary stub
EIP7251_FORK_EPOCH: 18446744073709551615
# WHISK # WHISK
WHISK_FORK_VERSION: 0x08000000 # temporary stub WHISK_FORK_VERSION: 0x08000000 # temporary stub
WHISK_FORK_EPOCH: 18446744073709551615 WHISK_FORK_EPOCH: 18446744073709551615
@ -163,6 +160,6 @@ NUMBER_OF_COLUMNS: 128
DATA_COLUMN_SIDECAR_SUBNET_COUNT: 32 DATA_COLUMN_SIDECAR_SUBNET_COUNT: 32
MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384 MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384
# [New in EIP7251] # [New in Electra:EIP7251]
MIN_PER_EPOCH_CHURN_LIMIT_EIP7251: 128000000000 # 2**7 * 10**9 (= 128,000,000,000) MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 128000000000 # 2**7 * 10**9 (= 128,000,000,000)
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 256000000000 # 2**8 * 10**9 (= 256,000,000,000) MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 256000000000 # 2**8 * 10**9 (= 256,000,000,000)

View File

@ -52,9 +52,6 @@ DENEB_FORK_EPOCH: 18446744073709551615
# Electra # Electra
ELECTRA_FORK_VERSION: 0x05000001 ELECTRA_FORK_VERSION: 0x05000001
ELECTRA_FORK_EPOCH: 18446744073709551615 ELECTRA_FORK_EPOCH: 18446744073709551615
# EIP7251
EIP7251_FORK_VERSION: 0x06000001 # temporary stub
EIP7251_FORK_EPOCH: 18446744073709551615
# WHISK # WHISK
WHISK_FORK_VERSION: 0x08000001 WHISK_FORK_VERSION: 0x08000001
WHISK_FORK_EPOCH: 18446744073709551615 WHISK_FORK_EPOCH: 18446744073709551615
@ -161,6 +158,6 @@ NUMBER_OF_COLUMNS: 128
DATA_COLUMN_SIDECAR_SUBNET_COUNT: 32 DATA_COLUMN_SIDECAR_SUBNET_COUNT: 32
MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384 MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384
# [New in EIP7251] # [New in Electra:EIP7251]
MIN_PER_EPOCH_CHURN_LIMIT_EIP7251: 64000000000 # 2**6 * 10**9 (= 64,000,000,000) MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 64000000000 # 2**6 * 10**9 (= 64,000,000,000)
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 128000000000 # 2**7 * 10**9 (= 128,000,000,000) MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 128000000000 # 2**7 * 10**9 (= 128,000,000,000)

View File

@ -1,28 +0,0 @@
# Mainnet preset - EIP7251
# Gwei values
# ---------------------------------------------------------------
# 2**5 * 10**9 (= 32,000,000,000) Gwei
MIN_ACTIVATION_BALANCE: 32000000000
# 2**11 * 10**9 (= 2,048,000,000,000) Gwei
MAX_EFFECTIVE_BALANCE_EIP7251: 2048000000000
# State list lengths
# ---------------------------------------------------------------
PENDING_BALANCE_DEPOSITS_LIMIT: 134217728
PENDING_PARTIAL_WITHDRAWALS_LIMIT: 134217728
PENDING_CONSOLIDATIONS_LIMIT: 262144
# Reward and penalty quotients
# ---------------------------------------------------------------
MIN_SLASHING_PENALTY_QUOTIENT_EIP7251: 4096
WHISTLEBLOWER_REWARD_QUOTIENT_EIP7251: 4096
# Max operations per block
# ---------------------------------------------------------------
MAX_CONSOLIDATIONS: 1
# Execution
# ---------------------------------------------------------------
# 2**3 (= 8) partial withdrawals
MAX_PARTIAL_WITHDRAWALS_PER_PAYLOAD: 8

View File

@ -1,11 +1,30 @@
# Mainnet preset - Electra # Mainnet preset - Electra
# Gwei values
# ---------------------------------------------------------------
# 2**5 * 10**9 (= 32,000,000,000) Gwei
MIN_ACTIVATION_BALANCE: 32000000000
# 2**11 * 10**9 (= 2,048,000,000,000) Gwei
MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000
# State list lengths
# ---------------------------------------------------------------
PENDING_BALANCE_DEPOSITS_LIMIT: 134217728
PENDING_PARTIAL_WITHDRAWALS_LIMIT: 134217728
PENDING_CONSOLIDATIONS_LIMIT: 262144
# Reward and penalty quotients
# ---------------------------------------------------------------
MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA: 4096
WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA: 4096
# # Max operations per block # # Max operations per block
# --------------------------------------------------------------- # ---------------------------------------------------------------
# `uint64(2**0)` (= 1) # `uint64(2**0)` (= 1)
MAX_ATTESTER_SLASHINGS_ELECTRA: 1 MAX_ATTESTER_SLASHINGS_ELECTRA: 1
# `uint64(2 * 3)` (= 8) # `uint64(2 * 3)` (= 8)
MAX_ATTESTATIONS_ELECTRA: 8 MAX_ATTESTATIONS_ELECTRA: 8
MAX_CONSOLIDATIONS: 1
# Execution # Execution
# --------------------------------------------------------------- # ---------------------------------------------------------------
@ -13,3 +32,5 @@ MAX_ATTESTATIONS_ELECTRA: 8
MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD: 8192 MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD: 8192
# 2**4 (= 16) exits # 2**4 (= 16) exits
MAX_EXECUTION_LAYER_EXITS: 16 MAX_EXECUTION_LAYER_EXITS: 16
# 2**3 (= 8) partial withdrawals
MAX_PARTIAL_WITHDRAWALS_PER_PAYLOAD: 8

View File

@ -1,30 +0,0 @@
# Minimal preset - EIP7251
# Gwei values
# ---------------------------------------------------------------
# 2**5 * 10**9 (= 32,000,000,000) Gwei
MIN_ACTIVATION_BALANCE: 32000000000
# 2**11 * 10**9 (= 2,048,000,000,000) Gwei
MAX_EFFECTIVE_BALANCE_EIP7251: 2048000000000
# State list lengths
# ---------------------------------------------------------------
PENDING_BALANCE_DEPOSITS_LIMIT: 134217728
# [customized] smaller queue
PENDING_PARTIAL_WITHDRAWALS_LIMIT: 64
# [customized] smaller queue
PENDING_CONSOLIDATIONS_LIMIT: 64
# Reward and penalty quotients
# ---------------------------------------------------------------
MIN_SLASHING_PENALTY_QUOTIENT_EIP7251: 4096
WHISTLEBLOWER_REWARD_QUOTIENT_EIP7251: 4096
# Max operations per block
# ---------------------------------------------------------------
MAX_CONSOLIDATIONS: 1
# Execution
# ---------------------------------------------------------------
# [customized] 2**1 (= 2)
MAX_PARTIAL_WITHDRAWALS_PER_PAYLOAD: 2

View File

@ -1,11 +1,32 @@
# Minimal preset - Electra # Minimal preset - Electra
# Gwei values
# ---------------------------------------------------------------
# 2**5 * 10**9 (= 32,000,000,000) Gwei
MIN_ACTIVATION_BALANCE: 32000000000
# 2**11 * 10**9 (= 2,048,000,000,000) Gwei
MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000
# State list lengths
# ---------------------------------------------------------------
PENDING_BALANCE_DEPOSITS_LIMIT: 134217728
# [customized] smaller queue
PENDING_PARTIAL_WITHDRAWALS_LIMIT: 64
# [customized] smaller queue
PENDING_CONSOLIDATIONS_LIMIT: 64
# Reward and penalty quotients
# ---------------------------------------------------------------
MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA: 4096
WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA: 4096
# # Max operations per block # # Max operations per block
# --------------------------------------------------------------- # ---------------------------------------------------------------
# `uint64(2**0)` (= 1) # `uint64(2**0)` (= 1)
MAX_ATTESTER_SLASHINGS_ELECTRA: 1 MAX_ATTESTER_SLASHINGS_ELECTRA: 1
# `uint64(2 * 3)` (= 8) # `uint64(2 * 3)` (= 8)
MAX_ATTESTATIONS_ELECTRA: 8 MAX_ATTESTATIONS_ELECTRA: 8
MAX_CONSOLIDATIONS: 1
# Execution # Execution
# --------------------------------------------------------------- # ---------------------------------------------------------------
@ -13,3 +34,5 @@ MAX_ATTESTATIONS_ELECTRA: 8
MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD: 4 MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD: 4
# 2**4 (= 16) exits # 2**4 (= 16) exits
MAX_EXECUTION_LAYER_EXITS: 16 MAX_EXECUTION_LAYER_EXITS: 16
# [customized] 2**1 (= 2)
MAX_PARTIAL_WITHDRAWALS_PER_PAYLOAD: 2

View File

@ -6,7 +6,6 @@ CAPELLA = 'capella'
DENEB = 'deneb' DENEB = 'deneb'
ELECTRA = 'electra' ELECTRA = 'electra'
EIP7594 = 'eip7594' EIP7594 = 'eip7594'
EIP7251 = 'eip7251'
WHISK = 'whisk' WHISK = 'whisk'

View File

@ -9,7 +9,6 @@ from .constants import (
ELECTRA, ELECTRA,
WHISK, WHISK,
EIP7594, EIP7594,
EIP7251,
) )
@ -21,7 +20,6 @@ PREVIOUS_FORK_OF = {
DENEB: CAPELLA, DENEB: CAPELLA,
ELECTRA: DENEB, ELECTRA: DENEB,
WHISK: CAPELLA, WHISK: CAPELLA,
EIP7251: DENEB,
EIP7594: DENEB, EIP7594: DENEB,
} }

View File

@ -5,7 +5,6 @@ from .capella import CapellaSpecBuilder
from .deneb import DenebSpecBuilder from .deneb import DenebSpecBuilder
from .electra import ElectraSpecBuilder from .electra import ElectraSpecBuilder
from .whisk import WhiskSpecBuilder from .whisk import WhiskSpecBuilder
from .eip7251 import EIP7251SpecBuilder
from .eip7594 import EIP7594SpecBuilder from .eip7594 import EIP7594SpecBuilder
@ -13,6 +12,6 @@ spec_builders = {
builder.fork: builder builder.fork: builder
for builder in ( for builder in (
Phase0SpecBuilder, AltairSpecBuilder, BellatrixSpecBuilder, CapellaSpecBuilder, DenebSpecBuilder, Phase0SpecBuilder, AltairSpecBuilder, BellatrixSpecBuilder, CapellaSpecBuilder, DenebSpecBuilder,
ElectraSpecBuilder, WhiskSpecBuilder, EIP7594SpecBuilder, EIP7251SpecBuilder, ElectraSpecBuilder, WhiskSpecBuilder, EIP7594SpecBuilder,
) )
} }

View File

@ -1,24 +0,0 @@
from typing import Dict
from .base import BaseSpecBuilder
from ..constants import EIP7251
class EIP7251SpecBuilder(BaseSpecBuilder):
fork: str = EIP7251
@classmethod
def imports(cls, preset_name: str):
return super().imports(preset_name) + f'''
from eth2spec.deneb import {preset_name} as deneb
'''
## TODO: deal with changed gindices
@classmethod
def hardcoded_ssz_dep_constants(cls) -> Dict[str, str]:
return {
'FINALIZED_ROOT_GINDEX': 'GeneralizedIndex(169)',
'CURRENT_SYNC_COMMITTEE_GINDEX': 'GeneralizedIndex(86)',
'NEXT_SYNC_COMMITTEE_GINDEX': 'GeneralizedIndex(87)',
}

View File

@ -1,3 +1,4 @@
from typing import Dict
from .base import BaseSpecBuilder from .base import BaseSpecBuilder
from ..constants import ELECTRA from ..constants import ELECTRA
@ -10,3 +11,13 @@ class ElectraSpecBuilder(BaseSpecBuilder):
return f''' return f'''
from eth2spec.deneb import {preset_name} as deneb from eth2spec.deneb import {preset_name} as deneb
''' '''
## TODO: deal with changed gindices
@classmethod
def hardcoded_ssz_dep_constants(cls) -> Dict[str, str]:
return {
'FINALIZED_ROOT_GINDEX': 'GeneralizedIndex(169)',
'CURRENT_SYNC_COMMITTEE_GINDEX': 'GeneralizedIndex(86)',
'NEXT_SYNC_COMMITTEE_GINDEX': 'GeneralizedIndex(87)',
}

View File

@ -1,137 +0,0 @@
# EIP7251 -- 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 EIP7251](#fork-to-eip7251)
- [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 the EIP7251 upgrade.
## Configuration
Warning: this configuration is not definitive.
| Name | Value |
| - | - |
| `EIP7251_FORK_VERSION` | `Version('0x06000000')` |
| `EIP7251_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 >= EIP7251_FORK_EPOCH:
return EIP7251_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 EIP7251
### 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 `EIP7251_FORK_EPOCH`.
Note that for the pure EIP7251 networks, we don't apply `upgrade_to_eip7251` since it starts with EIP7251 version logic.
### Upgrading the state
If `state.slot % SLOTS_PER_EPOCH == 0` and `compute_epoch_at_slot(state.slot) == EIP7251_FORK_EPOCH`,
an irregular state change is made to upgrade to EIP7251.
```python
def upgrade_to_eip7251(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=EIP7251_FORK_VERSION,
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,
# [New in EIP7251]
deposit_balance_to_consume=0,
exit_balance_to_consume=get_activation_exit_churn_limit(pre),
earliest_exit_epoch=max([v.exit_epoch for v in pre.validators if v.exit_epoch != FAR_FUTURE_EPOCH]) + 1,
consolidation_balance_to_consume=get_consolidation_churn_limit(pre),
earliest_consolidation_epoch=compute_activation_exit_epoch(get_current_epoch(pre)),
pending_balance_deposits=[],
pending_partial_withdrawals=[],
pending_consolidations=[],
)
# Ensure early adopters of compounding credentials go through the activation churn
for index, validator in enumerate(post.validators):
if has_compounding_withdrawal_credential(validator):
queue_excess_active_balance(post, ValidatorIndex(index))
return post
```

View File

@ -1,73 +0,0 @@
# EIP-7251 -- Honest Validator
## 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)
- [Prerequisites](#prerequisites)
- [Beacon chain responsibilities](#beacon-chain-responsibilities)
- [Block and sidecar proposal](#block-and-sidecar-proposal)
- [Constructing the `BeaconBlockBody`](#constructing-the-beaconblockbody)
- [ExecutionPayload](#executionpayload)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
## Introduction
This document represents the changes to be made in the code of an "honest validator".
## Prerequisites
This document is an extension of the [Deneb -- Honest Validator](../deneb/validator.md) guide.
All behaviors and definitions defined in this document, and documents it extends, carry over unless explicitly noted or overridden.
All terminology, constants, functions, and protocol mechanics defined in the updated [Beacon Chain doc of EIP-7251](./beacon-chain.md) are requisite for this document and used throughout.
Please see related Beacon Chain doc before continuing and use them as a reference throughout.
## Beacon chain responsibilities
All validator responsibilities remain unchanged other than those noted below.
### Block and sidecar proposal
#### Constructing the `BeaconBlockBody`
##### ExecutionPayload
`prepare_execution_payload` is updated from the Deneb specs.
*Note*: In this section, `state` is the state of the slot for the block proposal _without_ the block yet applied.
That is, `state` is the `previous_state` processed through any empty slots up to the assigned slot using `process_slots(previous_state, slot)`.
*Note*: The only change to `prepare_execution_payload` is the new definition of `get_expected_withdrawals`.
```python
def prepare_execution_payload(state: BeaconState,
safe_block_hash: Hash32,
finalized_block_hash: Hash32,
suggested_fee_recipient: ExecutionAddress,
execution_engine: ExecutionEngine) -> Optional[PayloadId]:
# Verify consistency of the parent hash with respect to the previous execution payload header
parent_hash = state.latest_execution_payload_header.block_hash
# Set the forkchoice head and initiate the payload build process
withdrawals, _ = get_expected_withdrawals(state) # [Modified in EIP-7251]
payload_attributes = PayloadAttributes(
timestamp=compute_timestamp_at_slot(state, state.slot),
prev_randao=get_randao_mix(state, get_current_epoch(state)),
suggested_fee_recipient=suggested_fee_recipient,
withdrawals=withdrawals,
parent_beacon_block_root=hash_tree_root(state.latest_block_header),
)
return execution_engine.notify_forkchoice_updated(
head_block_hash=parent_hash,
safe_block_hash=safe_block_hash,
finalized_block_hash=finalized_block_hash,
payload_attributes=payload_attributes,
)
```

File diff suppressed because it is too large Load Diff

View File

@ -139,9 +139,24 @@ def upgrade_to_electra(pre: deneb.BeaconState) -> BeaconState:
next_withdrawal_validator_index=pre.next_withdrawal_validator_index, next_withdrawal_validator_index=pre.next_withdrawal_validator_index,
# Deep history valid from Capella onwards # Deep history valid from Capella onwards
historical_summaries=pre.historical_summaries, historical_summaries=pre.historical_summaries,
# EIP6110 # [New in Electra:EIP6110]
deposit_receipts_start_index=UNSET_DEPOSIT_RECEIPTS_START_INDEX, # [New in Electra:EIP6110] deposit_receipts_start_index=UNSET_DEPOSIT_RECEIPTS_START_INDEX,
# [New in Electra:EIP7251]
deposit_balance_to_consume=0,
exit_balance_to_consume=get_activation_exit_churn_limit(pre),
earliest_exit_epoch=max([v.exit_epoch for v in pre.validators if v.exit_epoch != FAR_FUTURE_EPOCH]) + 1,
consolidation_balance_to_consume=get_consolidation_churn_limit(pre),
earliest_consolidation_epoch=compute_activation_exit_epoch(get_current_epoch(pre)),
pending_balance_deposits=[],
pending_partial_withdrawals=[],
pending_consolidations=[],
) )
# [New in Electra:EIP7251]
# Ensure early adopters of compounding credentials go through the activation churn
for index, validator in enumerate(post.validators):
if has_compounding_withdrawal_credential(validator):
queue_excess_active_balance(post, ValidatorIndex(index))
return post return post
``` ```

View File

@ -13,6 +13,7 @@
- [Attester slashings](#attester-slashings) - [Attester slashings](#attester-slashings)
- [Attestations](#attestations) - [Attestations](#attestations)
- [Deposits](#deposits) - [Deposits](#deposits)
- [Execution payload](#execution-payload)
- [Attesting](#attesting) - [Attesting](#attesting)
- [Construct attestation](#construct-attestation) - [Construct attestation](#construct-attestation)
- [Attestation aggregation](#attestation-aggregation) - [Attestation aggregation](#attestation-aggregation)
@ -81,6 +82,42 @@ def get_eth1_pending_deposit_count(state: BeaconState) -> uint64:
return uint64(0) return uint64(0)
``` ```
#### Execution payload
`prepare_execution_payload` is updated from the Deneb specs.
*Note*: In this section, `state` is the state of the slot for the block proposal _without_ the block yet applied.
That is, `state` is the `previous_state` processed through any empty slots up to the assigned slot using `process_slots(previous_state, slot)`.
*Note*: The only change to `prepare_execution_payload` is the new definition of `get_expected_withdrawals`.
```python
def prepare_execution_payload(state: BeaconState,
safe_block_hash: Hash32,
finalized_block_hash: Hash32,
suggested_fee_recipient: ExecutionAddress,
execution_engine: ExecutionEngine) -> Optional[PayloadId]:
# Verify consistency of the parent hash with respect to the previous execution payload header
parent_hash = state.latest_execution_payload_header.block_hash
# Set the forkchoice head and initiate the payload build process
withdrawals, _ = get_expected_withdrawals(state) # [Modified in EIP-7251]
payload_attributes = PayloadAttributes(
timestamp=compute_timestamp_at_slot(state, state.slot),
prev_randao=get_randao_mix(state, get_current_epoch(state)),
suggested_fee_recipient=suggested_fee_recipient,
withdrawals=withdrawals,
parent_beacon_block_root=hash_tree_root(state.latest_block_header),
)
return execution_engine.notify_forkchoice_updated(
head_block_hash=parent_hash,
safe_block_hash=safe_block_hash,
finalized_block_hash=finalized_block_hash,
payload_attributes=payload_attributes,
)
```
## Attesting ## Attesting
### Construct attestation ### Construct attestation

View File

@ -8,7 +8,6 @@ from eth2spec.utils import bls
from .exceptions import SkippedTest from .exceptions import SkippedTest
from .helpers.constants import ( from .helpers.constants import (
PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, ELECTRA, PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, ELECTRA,
EIP7251,
EIP7594, EIP7594,
WHISK, WHISK,
MINIMAL, MINIMAL,
@ -523,7 +522,6 @@ with_deneb_and_later = with_all_phases_from(DENEB)
with_electra_and_later = with_all_phases_from(ELECTRA) with_electra_and_later = with_all_phases_from(ELECTRA)
with_whisk_and_later = with_all_phases_from(WHISK, all_phases=ALLOWED_TEST_RUNNER_FORKS) with_whisk_and_later = with_all_phases_from(WHISK, all_phases=ALLOWED_TEST_RUNNER_FORKS)
with_eip7594_and_later = with_all_phases_from(EIP7594, all_phases=ALLOWED_TEST_RUNNER_FORKS) with_eip7594_and_later = with_all_phases_from(EIP7594, all_phases=ALLOWED_TEST_RUNNER_FORKS)
with_eip7251_and_later = with_all_phases_from(EIP7251, all_phases=ALLOWED_TEST_RUNNER_FORKS)
class quoted_str(str): class quoted_str(str):

View File

@ -1,7 +1,7 @@
from eth2spec.test.helpers.constants import MINIMAL from eth2spec.test.helpers.constants import MINIMAL
from eth2spec.test.context import ( from eth2spec.test.context import (
spec_state_test, spec_state_test,
with_eip7251_and_later, with_electra_and_later,
with_presets, with_presets,
always_bls, always_bls,
spec_test, spec_test,
@ -25,7 +25,7 @@ from eth2spec.test.helpers.withdrawals import (
# *********************** # ***********************
@with_eip7251_and_later @with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit") @with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state( @with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
@ -73,7 +73,7 @@ def test_basic_consolidation_in_current_consolidation_epoch(spec, state):
assert state.validators[0].exit_epoch == expected_exit_epoch assert state.validators[0].exit_epoch == expected_exit_epoch
@with_eip7251_and_later @with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit") @with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state( @with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
@ -262,7 +262,7 @@ def test_basic_consolidation_with_compounding_credential(spec, state):
assert state.validators[0].exit_epoch == expected_exit_epoch assert state.validators[0].exit_epoch == expected_exit_epoch
@with_eip7251_and_later @with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit") @with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state( @with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
@ -310,7 +310,7 @@ def test_consolidation_churn_limit_balance(spec, state):
assert state.validators[0].exit_epoch == expected_exit_epoch assert state.validators[0].exit_epoch == expected_exit_epoch
@with_eip7251_and_later @with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit") @with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state( @with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
@ -357,7 +357,7 @@ def test_consolidation_balance_larger_than_churn_limit(spec, state):
assert state.validators[0].exit_epoch == expected_exit_epoch assert state.validators[0].exit_epoch == expected_exit_epoch
@with_eip7251_and_later @with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit") @with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state( @with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
@ -404,7 +404,7 @@ def test_consolidation_balance_through_two_churn_epochs(spec, state):
assert state.consolidation_balance_to_consume == expected_balance assert state.consolidation_balance_to_consume == expected_balance
@with_eip7251_and_later @with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit") @with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state( @with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
@ -461,7 +461,7 @@ def test_multiple_consolidations_below_churn(spec, state):
assert state.validators[2 * i].exit_epoch == expected_exit_epoch assert state.validators[2 * i].exit_epoch == expected_exit_epoch
@with_eip7251_and_later @with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit") @with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state( @with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
@ -515,7 +515,7 @@ def test_multiple_consolidations_equal_churn(spec, state):
assert state.validators[2 * i].exit_epoch == expected_exit_epoch assert state.validators[2 * i].exit_epoch == expected_exit_epoch
@with_eip7251_and_later @with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit") @with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state( @with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
@ -593,7 +593,7 @@ def test_multiple_consolidations_above_churn(spec, state):
assert state.validators[2 * i].exit_epoch == expected_exit_epoch assert state.validators[2 * i].exit_epoch == expected_exit_epoch
@with_eip7251_and_later @with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit") @with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state( @with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
@ -651,8 +651,7 @@ def test_multiple_consolidations_equal_twice_churn(spec, state):
# Failing tests # Failing tests
@with_electra_and_later
@with_eip7251_and_later
@spec_state_test @spec_state_test
def test_invalid_source_equals_target(spec, state): def test_invalid_source_equals_target(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
@ -678,7 +677,7 @@ def test_invalid_source_equals_target(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_invalid_exceed_pending_consolidations_limit(spec, state): def test_invalid_exceed_pending_consolidations_limit(spec, state):
state.pending_consolidations = [ state.pending_consolidations = [
@ -727,7 +726,7 @@ def test_invalid_not_enough_consolidation_churn_available(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_invalid_exited_source(spec, state): def test_invalid_exited_source(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
@ -749,7 +748,7 @@ def test_invalid_exited_source(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_invalid_exited_target(spec, state): def test_invalid_exited_target(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
@ -772,7 +771,7 @@ def test_invalid_exited_target(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_invalid_inactive_source(spec, state): def test_invalid_inactive_source(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
@ -794,7 +793,7 @@ def test_invalid_inactive_source(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_invalid_inactive_target(spec, state): def test_invalid_inactive_target(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
@ -817,7 +816,7 @@ def test_invalid_inactive_target(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_invalid_no_execution_withdrawal_credential(spec, state): def test_invalid_no_execution_withdrawal_credential(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
@ -835,7 +834,7 @@ def test_invalid_no_execution_withdrawal_credential(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_invalid_different_credentials(spec, state): def test_invalid_different_credentials(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
@ -856,7 +855,7 @@ def test_invalid_different_credentials(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_source_signature(spec, state): def test_invalid_source_signature(spec, state):
@ -880,7 +879,7 @@ def test_invalid_source_signature(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_invalid_target_signature(spec, state): def test_invalid_target_signature(spec, state):
@ -904,7 +903,7 @@ def test_invalid_target_signature(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_invalid_before_specified_epoch(spec, state): def test_invalid_before_specified_epoch(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)

View File

@ -0,0 +1,284 @@
from eth2spec.test.helpers.deposits import (
build_deposit,
prepare_state_and_deposit,
run_deposit_processing_electra,
run_deposit_processing_electra_with_specific_fork_version,
sign_deposit_data,
)
from eth2spec.test.helpers.keys import privkeys, pubkeys
from eth2spec.test.context import (
spec_state_test,
with_electra_and_later,
always_bls,
)
@with_electra_and_later
@spec_state_test
def test_new_deposit_under_min_activation_balance(spec, state):
# fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validators)
# effective balance will be 1 EFFECTIVE_BALANCE_INCREMENT smaller because of this small decrement.
amount = spec.MIN_ACTIVATION_BALANCE - 1
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
@with_electra_and_later
@spec_state_test
def test_new_deposit_min(spec, state):
# fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validators)
amount = spec.MIN_DEPOSIT_AMOUNT
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
@with_electra_and_later
@spec_state_test
def test_new_deposit_between_min_and_max(spec, state):
# fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE_electra // 2
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
@with_electra_and_later
@spec_state_test
def test_new_deposit_max(spec, state):
# fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validators)
# effective balance will be exactly the same as balance.
amount = spec.MAX_EFFECTIVE_BALANCE_electra
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
@with_electra_and_later
@spec_state_test
def test_new_deposit_over_max(spec, state):
# fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE_electra + 1
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
# @with_electra_and_later
# @spec_state_test
# def test_top_up__max_effective_balance(spec, state):
# validator_index = 0
# amount = spec.MAX_EFFECTIVE_BALANCE_electra // 4
# deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
# state.balances[validator_index] = spec.MAX_EFFECTIVE_BALANCE_electra
# state.validators[validator_index].effective_balance = spec.MAX_EFFECTIVE_BALANCE_electra
# yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
# assert state.balances[validator_index] == spec.MAX_EFFECTIVE_BALANCE_electra + amount
# assert state.validators[validator_index].effective_balance == spec.MAX_EFFECTIVE_BALANCE_electra
@with_electra_and_later
@spec_state_test
@always_bls
def test_correct_sig_but_forked_state(spec, state):
validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE
# deposits will always be valid, regardless of the current fork
state.fork.current_version = spec.Version('0x1234abcd')
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
@with_electra_and_later
@spec_state_test
@always_bls
def test_incorrect_sig_new_deposit(spec, state):
# fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validators)
amount = spec.MIN_ACTIVATION_BALANCE
deposit = prepare_state_and_deposit(spec, state, validator_index, amount)
yield from run_deposit_processing_electra(spec, state, deposit, validator_index, effective=False)
@with_electra_and_later
@spec_state_test
def test_top_up__max_effective_balance(spec, state):
validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
state.balances[validator_index] = spec.MAX_EFFECTIVE_BALANCE
state.validators[validator_index].effective_balance = spec.MAX_EFFECTIVE_BALANCE
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
assert state.validators[validator_index].effective_balance == spec.MAX_EFFECTIVE_BALANCE
@with_electra_and_later
@spec_state_test
def test_top_up__less_effective_balance(spec, state):
validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
initial_balance = spec.MAX_EFFECTIVE_BALANCE - 1000
initial_effective_balance = spec.MAX_EFFECTIVE_BALANCE - spec.EFFECTIVE_BALANCE_INCREMENT
state.balances[validator_index] = initial_balance
state.validators[validator_index].effective_balance = initial_effective_balance
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
# unchanged effective balance
assert state.validators[validator_index].effective_balance == initial_effective_balance
@with_electra_and_later
@spec_state_test
def test_top_up__zero_balance(spec, state):
validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
initial_balance = 0
initial_effective_balance = 0
state.balances[validator_index] = initial_balance
state.validators[validator_index].effective_balance = initial_effective_balance
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
# unchanged effective balance
assert state.validators[validator_index].effective_balance == initial_effective_balance
@with_electra_and_later
@spec_state_test
@always_bls
def test_incorrect_sig_top_up(spec, state):
validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4
deposit = prepare_state_and_deposit(spec, state, validator_index, amount)
# invalid signatures, in top-ups, are allowed!
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
@with_electra_and_later
@spec_state_test
def test_incorrect_withdrawal_credentials_top_up(spec, state):
validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(b"junk")[1:]
deposit = prepare_state_and_deposit(
spec,
state,
validator_index,
amount,
withdrawal_credentials=withdrawal_credentials
)
# inconsistent withdrawal credentials, in top-ups, are allowed!
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
@with_electra_and_later
@spec_state_test
def test_invalid_wrong_deposit_for_deposit_count(spec, state):
deposit_data_leaves = [spec.DepositData() for _ in range(len(state.validators))]
# build root for deposit_1
index_1 = len(deposit_data_leaves)
pubkey_1 = pubkeys[index_1]
privkey_1 = privkeys[index_1]
_, _, deposit_data_leaves = build_deposit(
spec,
deposit_data_leaves,
pubkey_1,
privkey_1,
spec.MAX_EFFECTIVE_BALANCE,
withdrawal_credentials=b'\x00' * 32,
signed=True,
)
deposit_count_1 = len(deposit_data_leaves)
# build root for deposit_2
index_2 = len(deposit_data_leaves)
pubkey_2 = pubkeys[index_2]
privkey_2 = privkeys[index_2]
deposit_2, root_2, deposit_data_leaves = build_deposit(
spec,
deposit_data_leaves,
pubkey_2,
privkey_2,
spec.MAX_EFFECTIVE_BALANCE,
withdrawal_credentials=b'\x00' * 32,
signed=True,
)
# state has root for deposit_2 but is at deposit_count for deposit_1
state.eth1_data.deposit_root = root_2
state.eth1_data.deposit_count = deposit_count_1
yield from run_deposit_processing_electra(spec, state, deposit_2, index_2, valid=False)
@with_electra_and_later
@spec_state_test
def test_invalid_bad_merkle_proof(spec, state):
validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE
deposit = prepare_state_and_deposit(spec, state, validator_index, amount)
# mess up merkle branch
deposit.proof[5] = spec.Bytes32()
sign_deposit_data(spec, deposit.data, privkeys[validator_index])
yield from run_deposit_processing_electra(spec, state, deposit, validator_index, valid=False)
@with_electra_and_later
@spec_state_test
def test_key_validate_invalid_subgroup(spec, state):
validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE
# All-zero pubkey would not pass `bls.KeyValidate`, but `process_deposit` would not throw exception.
pubkey = b'\x00' * 48
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, pubkey=pubkey, signed=True)
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
@with_electra_and_later
@spec_state_test
def test_key_validate_invalid_decompression(spec, state):
validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE
# `deserialization_fails_infinity_with_true_b_flag` BLS G1 deserialization test case.
# This pubkey would not pass `bls.KeyValidate`, but `process_deposit` would not throw exception.
pubkey_hex = 'c01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
pubkey = bytes.fromhex(pubkey_hex)
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, pubkey=pubkey, signed=True)
yield from run_deposit_processing_electra(spec, state, deposit, validator_index)
@with_electra_and_later
@spec_state_test
@always_bls
def test_ineffective_deposit_with_bad_fork_version(spec, state):
yield from run_deposit_processing_electra_with_specific_fork_version(
spec,
state,
fork_version=spec.Version('0xAaBbCcDd'),
effective=False,
)

View File

@ -1,7 +1,7 @@
from eth2spec.test.context import ( from eth2spec.test.context import (
spec_state_test, spec_state_test,
expect_assertion_error, expect_assertion_error,
with_eip7251_and_later, with_electra_and_later,
with_presets, with_presets,
) )
from eth2spec.test.helpers.constants import MINIMAL from eth2spec.test.helpers.constants import MINIMAL
@ -20,8 +20,7 @@ from eth2spec.test.helpers.withdrawals import (
# Modified tests from 7002. Just testing EL-triggered exits, not partial withdrawals # Modified tests from 7002. Just testing EL-triggered exits, not partial withdrawals
@with_electra_and_later
@with_eip7251_and_later
@spec_state_test @spec_state_test
def test_basic_exit(spec, state): def test_basic_exit(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
@ -104,7 +103,7 @@ def test_basic_exit_with_full_partial_withdrawal_queue(spec, state):
# Invalid tests # Invalid tests
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_incorrect_source_address(spec, state): def test_incorrect_source_address(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
@ -129,7 +128,7 @@ def test_incorrect_source_address(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_incorrect_withdrawal_credential_prefix(spec, state): def test_incorrect_withdrawal_credential_prefix(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
@ -158,7 +157,7 @@ def test_incorrect_withdrawal_credential_prefix(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_on_exit_initiated_validator(spec, state): def test_on_exit_initiated_validator(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
@ -184,7 +183,7 @@ def test_on_exit_initiated_validator(spec, state):
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_activation_epoch_less_than_shard_committee_period(spec, state): def test_activation_epoch_less_than_shard_committee_period(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
@ -212,8 +211,7 @@ def test_activation_epoch_less_than_shard_committee_period(spec, state):
# Partial withdrawals tests # Partial withdrawals tests
@with_electra_and_later
@with_eip7251_and_later
@spec_state_test @spec_state_test
@with_presets([MINIMAL]) @with_presets([MINIMAL])
def test_basic_partial_withdrawal_request(spec, state): def test_basic_partial_withdrawal_request(spec, state):

View File

@ -0,0 +1,441 @@
from eth2spec.test.helpers.constants import (MINIMAL, MAINNET)
from eth2spec.test.context import (
spec_state_test,
with_electra_and_later,
with_presets,
always_bls,
spec_test, single_phase,
with_custom_state,
scaled_churn_balances_min_churn_limit,
)
from eth2spec.test.helpers.keys import pubkey_to_privkey
from eth2spec.test.helpers.voluntary_exits import (
run_voluntary_exit_processing,
sign_voluntary_exit,
)
# ********************
# * EXIT QUEUE TESTS *
# ********************
@with_electra_and_later
@spec_state_test
def test_min_balance_exit(spec, state):
# This state has 64 validators each with 32 ETH
expected_exit_epoch = spec.compute_activation_exit_epoch(spec.get_current_epoch(state))
churn_limit = spec.get_activation_exit_churn_limit(state)
# Set the balance to consume equal to churn limit
state.exit_balance_to_consume = churn_limit
yield "pre", state
# Exit validators, all which fit in the churn limit
spec.initiate_validator_exit(state, 0)
yield "post", state
# Check exit queue churn is set
assert state.exit_balance_to_consume == churn_limit - spec.MIN_ACTIVATION_BALANCE
# Check exit epoch
assert state.validators[0].exit_epoch == expected_exit_epoch
@with_electra_and_later
@spec_state_test
def test_min_balance_exits_up_to_churn(spec, state):
# This state has 64 validators each with 32 ETH
single_validator_balance = spec.MIN_ACTIVATION_BALANCE
expected_exit_epoch = spec.compute_activation_exit_epoch(spec.get_current_epoch(state))
churn_limit = spec.get_activation_exit_churn_limit(state)
# Set the balance to consume equal to churn limit
state.exit_balance_to_consume = churn_limit
yield "pre", state
# Exit validators, all which fit in the churn limit
for i in range(churn_limit // spec.MIN_ACTIVATION_BALANCE):
validator_index = i
spec.initiate_validator_exit(state, validator_index)
yield f"post{i}", state
# Check exit queue churn is set
assert state.exit_balance_to_consume == churn_limit - single_validator_balance * (i + 1)
# Check exit epoch
assert state.validators[validator_index].exit_epoch == expected_exit_epoch
yield "post", state
@with_electra_and_later
@spec_state_test
def test_min_balance_exits_above_churn(spec, state):
# This state has 64 validators each with 32 ETH
single_validator_balance = spec.MIN_ACTIVATION_BALANCE
expected_exit_epoch = spec.compute_activation_exit_epoch(spec.get_current_epoch(state))
churn_limit = spec.get_activation_exit_churn_limit(state)
# Set the balance to consume equal to churn limit
state.exit_balance_to_consume = churn_limit
yield "pre", state
# Exit validators, all which fit in the churn limit
for i in range(churn_limit // spec.MIN_ACTIVATION_BALANCE):
validator_index = i
spec.initiate_validator_exit(state, validator_index)
# Check exit queue churn is set
assert state.exit_balance_to_consume == churn_limit - single_validator_balance * (i + 1)
# Check exit epoch
assert state.validators[validator_index].exit_epoch == expected_exit_epoch
# Exit balance has been fully consumed
assert state.exit_balance_to_consume == 0
# Exit an additional validator, doesn't fit in the churn limit, so exit
# epoch is incremented
validator_index = churn_limit // spec.MIN_ACTIVATION_BALANCE
spec.initiate_validator_exit(state, validator_index)
yield "post", state
# Check exit epoch
assert state.validators[validator_index].exit_epoch == expected_exit_epoch + 1
# Check exit balance to consume is set
assert state.exit_balance_to_consume == churn_limit - single_validator_balance
# @with_electra_and_later
# @spec_state_test
# def test_exit_balance_to_consume_large_validator(spec, state):
# # Set 0th validator effective balance to 2048 ETH
# state.validators[0].effective_balance = spec.MAX_EFFECTIVE_BALANCE_electra
# churn_limit = spec.get_validator_churn_limit(state)
# expected_exit_epoch = spec.compute_activation_exit_epoch(spec.get_current_epoch(state))
# expected_exit_epoch += spec.MAX_EFFECTIVE_BALANCE_electra // churn_limit
# validator_index = 0
# spec.initiate_validator_exit(state, validator_index)
# # Check exit epoch
# assert state.validators[validator_index].exit_epoch == expected_exit_epoch
# # Check exit_balance_to_consume
# assert state.exit_balance_to_consume == churn_limit - (spec.MAX_EFFECTIVE_BALANCE_electra % churn_limit)
# # Check earliest_exit_epoch
# assert state.earliest_exit_epoch == expected_exit_epoch
@with_electra_and_later
@spec_state_test
@with_presets([MAINNET], "With CHURN_LIMIT_QUOTIENT=32, can't change validator balance without changing churn_limit")
def test_max_balance_exit(spec, state):
churn_limit = spec.get_activation_exit_churn_limit(state)
assert churn_limit == spec.MIN_ACTIVATION_BALANCE * spec.config.MIN_PER_EPOCH_CHURN_LIMIT
# Set 0th validator effective balance to 2048 ETH
state.validators[0].effective_balance = spec.MAX_EFFECTIVE_BALANCE_electra
yield 'pre', state
expected_exit_epoch = spec.compute_activation_exit_epoch(spec.get_current_epoch(state))
# Validator consumes exit churn for 16 epochs, exits at the 17th one
expected_exit_epoch += (spec.MAX_EFFECTIVE_BALANCE_electra // churn_limit)
validator_index = 0
spec.initiate_validator_exit(state, validator_index)
yield 'post', state
# Check exit epoch
assert state.validators[validator_index].exit_epoch == expected_exit_epoch
# Check exit_balance_to_consume
assert state.exit_balance_to_consume == churn_limit
# Check earliest_exit_epoch
assert state.earliest_exit_epoch == expected_exit_epoch
@with_electra_and_later
@spec_state_test
@with_presets([MAINNET], "With CHURN_LIMIT_QUOTIENT=32, can't change validator balance without changing churn_limit")
def test_exit_with_balance_equal_to_churn_limit(spec, state):
churn_limit = spec.get_activation_exit_churn_limit(state)
# Set 0th validator effective balance to churn_limit
state.validators[0].effective_balance = churn_limit
yield 'pre', state
validator_index = 0
spec.initiate_validator_exit(state, validator_index)
yield 'post', state
# Validator consumes churn limit fully in the current epoch
assert (state.validators[validator_index].exit_epoch ==
spec.compute_activation_exit_epoch(spec.get_current_epoch(state)))
# Check exit_balance_to_consume
assert state.exit_balance_to_consume == 0
# Check earliest_exit_epoch
assert state.earliest_exit_epoch == state.validators[validator_index].exit_epoch
@with_electra_and_later
@spec_state_test
@with_presets([MAINNET], "With CHURN_LIMIT_QUOTIENT=32, can't change validator balance without changing churn_limit")
def test_exit_churn_limit_balance_existing_churn_(spec, state):
cl = spec.get_activation_exit_churn_limit(state)
# set exit epoch to the first available one and set exit balance to consume to full churn limit
state.earliest_exit_epoch = spec.compute_activation_exit_epoch(spec.get_current_epoch(state))
state.exit_balance_to_consume = cl
# consume some churn in exit epoch
state.exit_balance_to_consume -= 1000000000
# Set 0th validator effective balance to the churn limit
state.validators[0].effective_balance = cl
yield 'pre', state
# The existing 1 ETH churn will push an extra epoch
expected_exit_epoch = state.earliest_exit_epoch + 1
yield 'post', state
validator_index = 0
spec.initiate_validator_exit(state, validator_index)
# Check exit epoch
assert state.validators[validator_index].exit_epoch == expected_exit_epoch
# Check balance consumed in exit epoch is the remainder 1 ETH
assert state.exit_balance_to_consume == cl - 1000000000
# check earliest exit epoch
assert expected_exit_epoch == state.earliest_exit_epoch
@with_electra_and_later
@spec_state_test
@with_presets([MAINNET], "With CHURN_LIMIT_QUOTIENT=32, can't change validator balance without changing churn_limit")
def test_multi_epoch_exit_existing_churn(spec, state):
cl = spec.get_activation_exit_churn_limit(state)
# set exit epoch to the first available one and set exit balance to consume to full churn limit
state.earliest_exit_epoch = spec.compute_activation_exit_epoch(spec.get_current_epoch(state))
state.exit_balance_to_consume = cl
# consume some churn in exit epoch
state.exit_balance_to_consume -= 1000000000
# Set 0th validator effective balance to 2x the churn limit
state.validators[0].effective_balance = 2 * cl
yield 'pre', state
# Two extra epochs will be necessary
expected_exit_epoch = spec.compute_activation_exit_epoch(spec.get_current_epoch(state)) + 2
validator_index = 0
spec.initiate_validator_exit(state, validator_index)
yield 'post', state
# Check exit epoch
assert state.validators[validator_index].exit_epoch == expected_exit_epoch
# Check balance consumed in exit epoch is the remainder 1 ETH
assert state.exit_balance_to_consume == cl - 1000000000
# check earliest exit epoch
assert expected_exit_epoch == state.earliest_exit_epoch
# Repurposed from phase0 voluntary exit tests, should disable the phase0 ones
def run_test_success_exit_queue(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
current_epoch = spec.get_current_epoch(state)
churn_limit = spec.get_activation_exit_churn_limit(state)
# exit `MAX_EXITS_PER_EPOCH`
max_exits = churn_limit // spec.MIN_ACTIVATION_BALANCE
initial_indices = spec.get_active_validator_indices(state, current_epoch)[:max_exits]
# Prepare a bunch of exits, based on the current state
exit_queue = []
for index in initial_indices:
privkey = pubkey_to_privkey[state.validators[index].pubkey]
signed_voluntary_exit = sign_voluntary_exit(
spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=index), privkey)
exit_queue.append(signed_voluntary_exit)
# Now run all the exits
for voluntary_exit in exit_queue:
# the function yields data, but we are just interested in running it here, ignore yields.
for _ in run_voluntary_exit_processing(spec, state, voluntary_exit):
continue
# exit an additional validator
validator_index = spec.get_active_validator_indices(state, current_epoch)[-1]
privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
signed_voluntary_exit = sign_voluntary_exit(
spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey)
# This is the interesting part of the test: on a pre-state with a full exit queue,
# when processing an additional exit, it results in an exit in a later epoch
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit)
for index in initial_indices:
assert (
state.validators[validator_index].exit_epoch ==
state.validators[index].exit_epoch + 1
)
assert state.earliest_exit_epoch == state.validators[validator_index].exit_epoch
consumed_churn = spec.MIN_ACTIVATION_BALANCE * (max_exits + 1)
assert state.exit_balance_to_consume == churn_limit - (consumed_churn % churn_limit)
@with_electra_and_later
@spec_state_test
def test_success_exit_queue__min_churn(spec, state):
yield from run_test_success_exit_queue(spec, state)
@with_electra_and_later
@with_presets([MINIMAL],
reason="mainnet config leads to larger validator set than limit of public/private keys pre-generated")
@spec_test
@with_custom_state(balances_fn=scaled_churn_balances_min_churn_limit,
threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
@single_phase
def test_success_exit_queue__scaled_churn(spec, state):
churn_limit = spec.get_activation_exit_churn_limit(state)
assert churn_limit > spec.config.MIN_PER_EPOCH_CHURN_LIMIT
yield from run_test_success_exit_queue(spec, state)
# After here no modifications were made, can just leave them in phase0 as is
@with_electra_and_later
@spec_state_test
def test_basic(spec, state):
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
signed_voluntary_exit = sign_voluntary_exit(
spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit)
assert state.validators[validator_index].exit_epoch == spec.compute_activation_exit_epoch(current_epoch)
@with_electra_and_later
@spec_state_test
@always_bls
def test_invalid_incorrect_signature(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
voluntary_exit = spec.VoluntaryExit(
epoch=current_epoch,
validator_index=validator_index,
)
signed_voluntary_exit = sign_voluntary_exit(spec, state, voluntary_exit, 12345)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)
@with_electra_and_later
@spec_state_test
def test_default_exit_epoch_subsequent_exit(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
signed_voluntary_exit = sign_voluntary_exit(
spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey)
# Exit one validator prior to this new one
exited_index = spec.get_active_validator_indices(state, current_epoch)[-1]
state.validators[exited_index].exit_epoch = current_epoch - 1
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit)
assert state.validators[validator_index].exit_epoch == spec.compute_activation_exit_epoch(current_epoch)
@with_electra_and_later
@spec_state_test
def test_invalid_validator_exit_in_future(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
voluntary_exit = spec.VoluntaryExit(
epoch=current_epoch + 1,
validator_index=validator_index,
)
signed_voluntary_exit = sign_voluntary_exit(spec, state, voluntary_exit, privkey)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)
@with_electra_and_later
@spec_state_test
def test_invalid_validator_incorrect_validator_index(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
voluntary_exit = spec.VoluntaryExit(
epoch=current_epoch,
validator_index=len(state.validators),
)
signed_voluntary_exit = sign_voluntary_exit(spec, state, voluntary_exit, privkey)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)
@with_electra_and_later
@spec_state_test
def test_invalid_validator_not_active(spec, state):
current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
state.validators[validator_index].activation_epoch = spec.FAR_FUTURE_EPOCH
signed_voluntary_exit = sign_voluntary_exit(
spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)
@with_electra_and_later
@spec_state_test
def test_invalid_validator_already_exited(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow validator able to exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
# but validator already has exited
state.validators[validator_index].exit_epoch = current_epoch + 2
signed_voluntary_exit = sign_voluntary_exit(
spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)
@with_electra_and_later
@spec_state_test
def test_invalid_validator_not_active_long_enough(spec, state):
current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
signed_voluntary_exit = sign_voluntary_exit(
spec, state, spec.VoluntaryExit(epoch=current_epoch, validator_index=validator_index), privkey)
assert (
current_epoch - state.validators[validator_index].activation_epoch <
spec.config.SHARD_COMMITTEE_PERIOD
)
yield from run_voluntary_exit_processing(spec, state, signed_voluntary_exit, valid=False)

View File

@ -1,11 +1,11 @@
from eth2spec.test.helpers.epoch_processing import run_epoch_processing_with from eth2spec.test.helpers.epoch_processing import run_epoch_processing_with
from eth2spec.test.context import ( from eth2spec.test.context import (
spec_state_test, spec_state_test,
with_eip7251_and_later, with_electra_and_later,
) )
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_pending_deposit_min_activation_balance(spec, state): def test_pending_deposit_min_activation_balance(spec, state):
index = 0 index = 0
@ -23,7 +23,7 @@ def test_pending_deposit_min_activation_balance(spec, state):
assert state.pending_balance_deposits == [] assert state.pending_balance_deposits == []
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_pending_deposit_balance_equal_churn(spec, state): def test_pending_deposit_balance_equal_churn(spec, state):
index = 0 index = 0
@ -40,7 +40,7 @@ def test_pending_deposit_balance_equal_churn(spec, state):
assert state.pending_balance_deposits == [] assert state.pending_balance_deposits == []
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_pending_deposit_balance_above_churn(spec, state): def test_pending_deposit_balance_above_churn(spec, state):
index = 0 index = 0
@ -64,7 +64,7 @@ def test_pending_deposit_balance_above_churn(spec, state):
] ]
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_pending_deposit_preexisting_churn(spec, state): def test_pending_deposit_preexisting_churn(spec, state):
index = 0 index = 0
@ -85,7 +85,7 @@ def test_pending_deposit_preexisting_churn(spec, state):
assert state.pending_balance_deposits == [] assert state.pending_balance_deposits == []
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_multiple_pending_deposits_below_churn(spec, state): def test_multiple_pending_deposits_below_churn(spec, state):
amount = 10**9 amount = 10**9
@ -106,7 +106,7 @@ def test_multiple_pending_deposits_below_churn(spec, state):
assert state.pending_balance_deposits == [] assert state.pending_balance_deposits == []
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_multiple_pending_deposits_above_churn(spec, state): def test_multiple_pending_deposits_above_churn(spec, state):
# set third deposit to be over the churn # set third deposit to be over the churn

View File

@ -1,7 +1,7 @@
from eth2spec.test.helpers.epoch_processing import run_epoch_processing_with from eth2spec.test.helpers.epoch_processing import run_epoch_processing_with
from eth2spec.test.context import ( from eth2spec.test.context import (
spec_state_test, spec_state_test,
with_eip7251_and_later, with_electra_and_later,
) )
# *********************** # ***********************
@ -9,7 +9,7 @@ from eth2spec.test.context import (
# *********************** # ***********************
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_basic_pending_consolidation(spec, state): def test_basic_pending_consolidation(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
@ -78,7 +78,7 @@ def test_consolidation_not_yet_withdrawable_validator(spec, state):
assert state.pending_consolidations == pre_pending_consolidations assert state.pending_consolidations == pre_pending_consolidations
@with_eip7251_and_later @with_electra_and_later
@spec_state_test @spec_state_test
def test_skip_consolidation_when_source_slashed(spec, state): def test_skip_consolidation_when_source_slashed(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)

View File

@ -1,11 +1,11 @@
from eth2spec.test.context import ( from eth2spec.test.context import (
single_phase, single_phase,
spec_test, spec_test,
with_eip7251_and_later, with_electra_and_later,
) )
@with_eip7251_and_later @with_electra_and_later
@spec_test @spec_test
@single_phase @single_phase
def test_withdrawals(spec): def test_withdrawals(spec):

View File

@ -19,7 +19,6 @@ CUSTODY_GAME = SpecForkName('custody_game')
DAS = SpecForkName('das') DAS = SpecForkName('das')
ELECTRA = SpecForkName('electra') ELECTRA = SpecForkName('electra')
WHISK = SpecForkName('whisk') WHISK = SpecForkName('whisk')
EIP7251 = SpecForkName('eip7251')
EIP7594 = SpecForkName('eip7594') EIP7594 = SpecForkName('eip7594')
# #
@ -38,7 +37,6 @@ ALL_PHASES = (
DENEB, DENEB,
ELECTRA, ELECTRA,
# Experimental patches # Experimental patches
EIP7251,
EIP7594, EIP7594,
) )
# The forks that have light client specs # The forks that have light client specs
@ -59,7 +57,6 @@ PREVIOUS_FORK_OF = {
ELECTRA: DENEB, ELECTRA: DENEB,
# Experimental patches # Experimental patches
WHISK: CAPELLA, WHISK: CAPELLA,
EIP7251: DENEB,
EIP7594: DENEB, EIP7594: DENEB,
} }

View File

@ -1,6 +1,6 @@
from .constants import ( from .constants import (
PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB,
ELECTRA, WHISK, EIP7251, ELECTRA, WHISK,
PREVIOUS_FORK_OF, PREVIOUS_FORK_OF,
) )
@ -41,10 +41,6 @@ def is_post_electra(spec):
return is_post_fork(spec.fork, ELECTRA) return is_post_fork(spec.fork, ELECTRA)
def is_post_eip7251(spec):
return is_post_fork(spec.fork, EIP7251)
def is_post_whisk(spec): def is_post_whisk(spec):
return is_post_fork(spec.fork, WHISK) return is_post_fork(spec.fork, WHISK)

View File

@ -6,7 +6,7 @@ from eth2spec.test.helpers.execution_payload import (
compute_el_header_block_hash, compute_el_header_block_hash,
) )
from eth2spec.test.helpers.forks import ( from eth2spec.test.helpers.forks import (
is_post_altair, is_post_bellatrix, is_post_capella, is_post_electra, is_post_whisk, is_post_eip7251, is_post_altair, is_post_bellatrix, is_post_capella, is_post_electra, is_post_whisk,
) )
from eth2spec.test.helpers.keys import pubkeys from eth2spec.test.helpers.keys import pubkeys
from eth2spec.test.helpers.whisk import compute_whisk_initial_tracker_cached, compute_whisk_initial_k_commitment_cached from eth2spec.test.helpers.whisk import compute_whisk_initial_tracker_cached, compute_whisk_initial_k_commitment_cached
@ -148,7 +148,7 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
for i in range(spec.WHISK_PROPOSER_TRACKERS_COUNT): for i in range(spec.WHISK_PROPOSER_TRACKERS_COUNT):
state.whisk_proposer_trackers[i] = compute_whisk_initial_tracker_cached(i % vc) state.whisk_proposer_trackers[i] = compute_whisk_initial_tracker_cached(i % vc)
if is_post_eip7251(spec): if is_post_electra(spec):
state.deposit_balance_to_consume = 0 state.deposit_balance_to_consume = 0
state.exit_balance_to_consume = 0 state.exit_balance_to_consume = 0
state.earliest_exit_epoch = spec.GENESIS_EPOCH state.earliest_exit_epoch = spec.GENESIS_EPOCH

View File

@ -4,7 +4,7 @@ from eth2spec.test.context import (
) )
from eth2spec.test.helpers.constants import UINT64_MAX from eth2spec.test.helpers.constants import UINT64_MAX
from eth2spec.test.helpers.forks import ( from eth2spec.test.helpers.forks import (
is_post_altair, is_post_bellatrix, is_post_eip7251, is_post_altair, is_post_bellatrix, is_post_electra,
) )
@ -58,8 +58,8 @@ def test_incentives(spec, state):
assert spec.MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX <= spec.WHISTLEBLOWER_REWARD_QUOTIENT assert spec.MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX <= spec.WHISTLEBLOWER_REWARD_QUOTIENT
elif is_post_altair(spec): elif is_post_altair(spec):
assert spec.MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR <= spec.WHISTLEBLOWER_REWARD_QUOTIENT assert spec.MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR <= spec.WHISTLEBLOWER_REWARD_QUOTIENT
elif is_post_eip7251(spec): elif is_post_electra(spec):
assert spec.MIN_SLASHING_PENALTY_QUOTIENT_EIP7251 <= spec.WHISTLEBLOWER_REWARD_QUOTIENT_EIP7251 assert spec.MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA <= spec.WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA
else: else:
assert spec.MIN_SLASHING_PENALTY_QUOTIENT <= spec.WHISTLEBLOWER_REWARD_QUOTIENT assert spec.MIN_SLASHING_PENALTY_QUOTIENT <= spec.WHISTLEBLOWER_REWARD_QUOTIENT