mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-02-22 15:28:11 +00:00
Add EIP-7251 to Electra fork
This commit is contained in:
parent
77ec547cc7
commit
ce3931653d
1
.gitignore
vendored
1
.gitignore
vendored
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
|
@ -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
|
||||||
|
@ -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
|
|
@ -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
|
||||||
|
@ -6,7 +6,6 @@ CAPELLA = 'capella'
|
|||||||
DENEB = 'deneb'
|
DENEB = 'deneb'
|
||||||
ELECTRA = 'electra'
|
ELECTRA = 'electra'
|
||||||
EIP7594 = 'eip7594'
|
EIP7594 = 'eip7594'
|
||||||
EIP7251 = 'eip7251'
|
|
||||||
WHISK = 'whisk'
|
WHISK = 'whisk'
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -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)',
|
|
||||||
}
|
|
@ -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)',
|
||||||
|
}
|
||||||
|
@ -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
|
|
||||||
```
|
|
@ -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
@ -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
|
||||||
```
|
```
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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)
|
||||||
|
@ -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,
|
||||||
|
)
|
@ -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):
|
||||||
|
@ -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)
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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):
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user