From 034909ddb63410017b329d15417d54863c40c14a Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Mon, 15 Apr 2024 19:45:40 -0600 Subject: [PATCH] Merge in EIP-7251 tests to Electra --- .circleci/config.yml | 16 - .github/workflows/run-tests.yml | 2 +- Makefile | 2 +- specs/_features/eip7251/beacon-chain.md | 1124 ----------------- .../block_processing/test_process_deposit.py | 6 +- .../test/capella/sanity/test_blocks.py | 6 +- .../test_process_registry_updates.py | 4 +- .../test/eip7251/block_processing/__init__.py | 0 .../block_processing/test_voluntary_exit.py | 441 ------- .../test/eip7251/unittests/__init__.py | 0 .../test_process_consolidation.py | 8 +- .../block_processing/test_process_deposit.py | 40 +- ...rocess_execution_layer_withdraw_request.py | 44 +- .../test_process_voluntary_exit.py | 22 +- .../test_process_effective_balance_updates.py | 4 +- .../test_process_pending_balance_deposits.py | 0 .../test_process_pending_consolidations.py | 4 +- .../unittests}/__init__.py | 0 .../unittests/test_config_invariants.py | 0 .../pyspec/eth2spec/test/helpers/deposits.py | 8 +- ... => execution_layer_withdrawal_request.py} | 14 +- .../test/helpers/execution_payload.py | 28 +- .../test/helpers/proposer_slashings.py | 10 +- .../eth2spec/test/helpers/withdrawals.py | 4 +- .../block_processing/test_process_deposit.py | 8 +- .../test_process_effective_balance_updates.py | 6 +- .../test_process_registry_updates.py | 12 +- .../test/phase0/sanity/test_blocks.py | 6 +- 28 files changed, 119 insertions(+), 1700 deletions(-) delete mode 100644 specs/_features/eip7251/beacon-chain.md delete mode 100644 tests/core/pyspec/eth2spec/test/eip7251/block_processing/__init__.py delete mode 100644 tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_voluntary_exit.py delete mode 100644 tests/core/pyspec/eth2spec/test/eip7251/unittests/__init__.py rename tests/core/pyspec/eth2spec/test/{eip7251 => electra}/block_processing/test_process_consolidation.py (99%) rename tests/core/pyspec/eth2spec/test/{eip7251 => electra}/block_processing/test_process_deposit.py (84%) rename tests/core/pyspec/eth2spec/test/{eip7251 => electra}/block_processing/test_process_execution_layer_withdraw_request.py (98%) rename tests/core/pyspec/eth2spec/test/{eip7251 => electra}/block_processing/test_process_voluntary_exit.py (98%) rename tests/core/pyspec/eth2spec/test/{eip7251 => electra}/epoch_processing/test_process_effective_balance_updates.py (79%) rename tests/core/pyspec/eth2spec/test/{eip7251 => electra}/epoch_processing/test_process_pending_balance_deposits.py (100%) rename tests/core/pyspec/eth2spec/test/{eip7251 => electra}/epoch_processing/test_process_pending_consolidations.py (99%) rename tests/core/pyspec/eth2spec/test/{eip7251 => electra/unittests}/__init__.py (100%) rename tests/core/pyspec/eth2spec/test/{eip7251 => electra}/unittests/test_config_invariants.py (100%) rename tests/core/pyspec/eth2spec/test/helpers/{execution_layer_exits.py => execution_layer_withdrawal_request.py} (58%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8bf641a97..bf8b7ada8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -168,19 +168,6 @@ jobs: command: make citest fork=electra - store_test_results: path: tests/core/pyspec/test-reports - test-eip7251: - docker: - - image: circleci/python:3.9 - working_directory: ~/specs-repo - steps: - - restore_cache: - key: v3-specs-repo-{{ .Branch }}-{{ .Revision }} - - restore_pyspec_cached_venv - - run: - name: Run py-tests - command: make citest fork=eip7251 - - store_test_results: - path: tests/core/pyspec/test-reports test-whisk: docker: - image: circleci/python:3.9 @@ -330,9 +317,6 @@ workflows: - test-electra: requires: - install_pyspec_test - - test-eip7251: - requires: - - install_pyspec_test - test-whisk: requires: - install_pyspec_test diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 536704bb6..0e9126e39 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -71,7 +71,7 @@ jobs: needs: [preclear,lint,codespell,table_of_contents] strategy: matrix: - version: ["phase0", "altair", "bellatrix", "capella", "deneb", "electra", "eip7251", "whisk", "eip7594"] + version: ["phase0", "altair", "bellatrix", "capella", "deneb", "electra", "whisk", "eip7594"] steps: - name: Checkout this repo uses: actions/checkout@v3.2.0 diff --git a/Makefile b/Makefile index 1cda64d80..1025a2a1e 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ MARKDOWN_FILES = $(wildcard $(SPEC_DIR)/*/*.md) \ $(wildcard $(SPEC_DIR)/_features/*/*/*.md) \ $(wildcard $(SSZ_DIR)/*.md) -ALL_EXECUTABLE_SPEC_NAMES = phase0 altair bellatrix capella deneb electra eip7251 whisk +ALL_EXECUTABLE_SPEC_NAMES = phase0 altair bellatrix capella deneb electra whisk # The parameters for commands. Use `foreach` to avoid listing specs again. COVERAGE_SCOPE := $(foreach S,$(ALL_EXECUTABLE_SPEC_NAMES), --cov=eth2spec.$S.$(TEST_PRESET_TYPE)) PYLINT_SCOPE := $(foreach S,$(ALL_EXECUTABLE_SPEC_NAMES), ./eth2spec/$S) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md deleted file mode 100644 index 5e2b8888b..000000000 --- a/specs/_features/eip7251/beacon-chain.md +++ /dev/null @@ -1,1124 +0,0 @@ -# EIP7251 - Spec - -## Table of contents - - - - - -- [Introduction](#introduction) -- [Constants](#constants) - - [Misc](#misc) - - [Withdrawal prefixes](#withdrawal-prefixes) - - [Domains](#domains) -- [Presets](#presets) - - [Gwei values](#gwei-values) - - [Rewards and penalties](#rewards-and-penalties) - - [Max operations per block](#max-operations-per-block) - - [Execution](#execution) - - [State list lengths](#state-list-lengths) -- [Configuration](#configuration) - - [Validator cycle](#validator-cycle) -- [Containers](#containers) - - [New containers](#new-containers) - - [New `PendingBalanceDeposit`](#new-pendingbalancedeposit) - - [New `PendingPartialWithdrawal`](#new-pendingpartialwithdrawal) - - [New `ExecutionLayerWithdrawRequest`](#new-executionlayerwithdrawrequest) - - [New `Consolidation`](#new-consolidation) - - [New `SignedConsolidation`](#new-signedconsolidation) - - [New `PendingConsolidation`](#new-pendingconsolidation) - - [Extended Containers](#extended-containers) - - [`BeaconState`](#beaconstate) - - [`BeaconBlockBody`](#beaconblockbody) - - [`ExecutionPayload`](#executionpayload) - - [`ExecutionPayloadHeader`](#executionpayloadheader) -- [Helpers](#helpers) - - [Predicates](#predicates) - - [Updated `is_eligible_for_activation_queue`](#updated-is_eligible_for_activation_queue) - - [New `is_compounding_withdrawal_credential`](#new-is_compounding_withdrawal_credential) - - [New `has_compounding_withdrawal_credential`](#new-has_compounding_withdrawal_credential) - - [New `has_execution_withdrawal_credential`](#new-has_execution_withdrawal_credential) - - [Updated `is_fully_withdrawable_validator`](#updated-is_fully_withdrawable_validator) - - [Updated `is_partially_withdrawable_validator`](#updated-is_partially_withdrawable_validator) - - [Beacon state accessors](#beacon-state-accessors) - - [New `get_validator_max_effective_balance`](#new-get_validator_max_effective_balance) - - [New `get_churn_limit`](#new-get_churn_limit) - - [New `get_activation_exit_churn_limit`](#new-get_activation_exit_churn_limit) - - [New `get_consolidation_churn_limit`](#new-get_consolidation_churn_limit) - - [New `get_active_balance`](#new-get_active_balance) - - [New `get_pending_balance_to_withdraw`](#new-get_pending_balance_to_withdraw) - - [Beacon state mutators](#beacon-state-mutators) - - [Updated `initiate_validator_exit`](#updated--initiate_validator_exit) - - [New `switch_to_compounding_validator`](#new-switch_to_compounding_validator) - - [New `queue_excess_active_balance`](#new-queue_excess_active_balance) - - [New `compute_exit_epoch_and_update_churn`](#new-compute_exit_epoch_and_update_churn) - - [New `compute_consolidation_epoch_and_update_churn`](#new-compute_consolidation_epoch_and_update_churn) - - [Updated `slash_validator`](#updated-slash_validator) -- [Beacon chain state transition function](#beacon-chain-state-transition-function) - - [Epoch processing](#epoch-processing) - - [Updated `process_epoch`](#updated-process_epoch) - - [Updated `process_registry_updates`](#updated--process_registry_updates) - - [New `process_pending_balance_deposits`](#new-process_pending_balance_deposits) - - [New `process_pending_consolidations`](#new-process_pending_consolidations) - - [Updated `process_effective_balance_updates`](#updated-process_effective_balance_updates) - - [Block processing](#block-processing) - - [Updated `get_expected_withdrawals`](#updated-get_expected_withdrawals) - - [Updated `process_withdrawals`](#updated-process_withdrawals) - - [Operations](#operations) - - [Updated `process_operations`](#updated-process_operations) - - [Deposits](#deposits) - - [Updated `apply_deposit`](#updated--apply_deposit) - - [New `is_valid_deposit_signature`](#new-is_valid_deposit_signature) - - [Modified `add_validator_to_registry`](#modified-add_validator_to_registry) - - [Updated `get_validator_from_deposit`](#updated-get_validator_from_deposit) - - [Withdrawals](#withdrawals) - - [New `process_execution_layer_withdraw_request`](#new-process_execution_layer_withdraw_request) - - [Consolidations](#consolidations) - - [New `process_consolidation`](#new-process_consolidation) - - [Voluntary exits](#voluntary-exits) - - [Updated `process_voluntary_exit`](#updated-process_voluntary_exit) -- [Testing](#testing) - - - - -## Introduction - -See [a modest proposal](https://notes.ethereum.org/@mikeneuder/increase-maxeb), the [diff view](https://github.com/michaelneuder/consensus-specs/pull/3/files) and -[security considerations](https://notes.ethereum.org/@fradamt/meb-increase-security). - -*Note:* This specification is built upon [Deneb](../../deneb/beacon-chain.md). - -## Constants - -The following values are (non-configurable) constants used throughout the specification. - -### Misc - -| Name | Value | -| - | - | -| `FULL_EXIT_REQUEST_AMOUNT` | `uint64(0)` | - -### Withdrawal prefixes - -| Name | Value | -| - | - | -| `BLS_WITHDRAWAL_PREFIX` | `Bytes1('0x00')` | -| `ETH1_ADDRESS_WITHDRAWAL_PREFIX` | `Bytes1('0x01')` | -| `COMPOUNDING_WITHDRAWAL_PREFIX` | `Bytes1('0x02')` | - -### Domains - -| Name | Value | -| - | - | -| `DOMAIN_CONSOLIDATION` | `DomainType('0x0B000000')` | - -## Presets - -### Gwei values - -| Name | Value | -| - | - | -| `MIN_ACTIVATION_BALANCE` | `Gwei(2**5 * 10**9)` (= 32,000,000,000) | -| `MAX_EFFECTIVE_BALANCE_EIP7251` | `Gwei(2**11 * 10**9)` (= 2048,000,000,000) | - -### Rewards and penalties - -| Name | Value | -| - | - | -| `MIN_SLASHING_PENALTY_QUOTIENT_EIP7251` | `uint64(2**12)` (= 4,096) | -| `WHISTLEBLOWER_REWARD_QUOTIENT_EIP7251` | `uint64(2**12)` (= 4,096) | - -### Max operations per block - -| Name | Value | -| - | - | -| `MAX_CONSOLIDATIONS` | `uint64(1)` | - -### Execution - -| Name | Value | Description | -| - | - | - | -| `MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD` | `uint64(16)` | -| `MAX_PARTIAL_WITHDRAWALS_PER_PAYLOAD` | `uint64(2**3)` (= 8) | Maximum amount of partial withdrawals allowed in each payload | - -### State list lengths - -| Name | Value | Unit | -| - | - | :-: | -| `PENDING_BALANCE_DEPOSITS_LIMIT` | `uint64(2**27)` (= 134,217,728) | pending balance deposits | -| `PENDING_PARTIAL_WITHDRAWALS_LIMIT` | `uint64(2**27)` (= 134,217,728) | pending partial withdrawals | -| `PENDING_CONSOLIDATIONS_LIMIT` | `uint64(2**18)` (= 262,144) | pending consolidations | - - -## Configuration - -### Validator cycle - -| Name | Value | -| - | - | -| `MIN_PER_EPOCH_CHURN_LIMIT_EIP7251` | `Gwei(2**7 * 10**9)` (= 128,000,000,000) | # Equivalent to 4 32 ETH validators -| `MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT` | `Gwei(2**8 * 10**9)` (256,000,000,000) | - - -## Containers - -### New containers - -#### New `PendingBalanceDeposit` - -```python -class PendingBalanceDeposit(Container): - index: ValidatorIndex - amount: Gwei -``` - -#### New `PendingPartialWithdrawal` - -```python -class PendingPartialWithdrawal(Container): - index: ValidatorIndex - amount: Gwei - withdrawable_epoch: Epoch -``` -#### New `ExecutionLayerWithdrawRequest` - -```python -class ExecutionLayerWithdrawRequest(Container): - source_address: ExecutionAddress - validator_pubkey: BLSPubkey - amount: Gwei -``` - -#### New `Consolidation` - -```python -class Consolidation(Container): - source_index: ValidatorIndex - target_index: ValidatorIndex - epoch: Epoch -``` - -#### New `SignedConsolidation` -```python -class SignedConsolidation(Container): - message: Consolidation - signature: BLSSignature -``` - -#### New `PendingConsolidation` -```python -class PendingConsolidation(Container): - source_index: ValidatorIndex - target_index: ValidatorIndex -``` - -### Extended Containers - -#### `BeaconState` - -```python -class BeaconState(Container): - # Versioning - genesis_time: uint64 - genesis_validators_root: Root - slot: Slot - fork: Fork - # History - latest_block_header: BeaconBlockHeader - block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] - state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] - historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT] - # Eth1 - eth1_data: Eth1Data - eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH] - eth1_deposit_index: uint64 - # Registry - validators: List[Validator, VALIDATOR_REGISTRY_LIMIT] - balances: List[Gwei, VALIDATOR_REGISTRY_LIMIT] - # Randomness - randao_mixes: Vector[Bytes32, EPOCHS_PER_HISTORICAL_VECTOR] - # Slashings - slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR] # Per-epoch sums of slashed effective balances - # Participation - previous_epoch_participation: List[ParticipationFlags, VALIDATOR_REGISTRY_LIMIT] - current_epoch_participation: List[ParticipationFlags, VALIDATOR_REGISTRY_LIMIT] - # Finality - justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH] # Bit set for every recent justified epoch - previous_justified_checkpoint: Checkpoint - current_justified_checkpoint: Checkpoint - finalized_checkpoint: Checkpoint - # Inactivity - inactivity_scores: List[uint64, VALIDATOR_REGISTRY_LIMIT] - # Sync - current_sync_committee: SyncCommittee - next_sync_committee: SyncCommittee - # Execution - latest_execution_payload_header: ExecutionPayloadHeader - # Withdrawals - next_withdrawal_index: WithdrawalIndex - next_withdrawal_validator_index: ValidatorIndex - # Deep history valid from Capella onwards - historical_summaries: List[HistoricalSummary, HISTORICAL_ROOTS_LIMIT] - # EIP-7251 - deposit_balance_to_consume: Gwei # [New in EIP-7251] - exit_balance_to_consume: Gwei # [New in EIP-7251] - earliest_exit_epoch: Epoch # [New in EIP-7251] - consolidation_balance_to_consume: Gwei # [New in EIP-7251] - earliest_consolidation_epoch: Epoch # [New in EIP-7251] - pending_balance_deposits: List[PendingBalanceDeposit, PENDING_BALANCE_DEPOSITS_LIMIT] # [New in EIP-7251] - pending_partial_withdrawals: List[PendingPartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT] # [New in EIP-7251] - pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT] # [New in EIP-7251] -``` - -#### `BeaconBlockBody` - -```python -class BeaconBlockBody(Container): - randao_reveal: BLSSignature - eth1_data: Eth1Data # Eth1 data vote - graffiti: Bytes32 # Arbitrary data - # Operations - proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS] - attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS] - attestations: List[Attestation, MAX_ATTESTATIONS] - deposits: List[Deposit, MAX_DEPOSITS] - voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS] - sync_aggregate: SyncAggregate - # Execution - execution_payload: ExecutionPayload - bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES] - blob_kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK] - consolidations: List[SignedConsolidation, MAX_CONSOLIDATIONS] # [New in EIP-7251] -``` - -#### `ExecutionPayload` - -```python -class ExecutionPayload(Container): - # Execution block header fields - parent_hash: Hash32 - fee_recipient: ExecutionAddress # 'beneficiary' in the yellow paper - state_root: Bytes32 - receipts_root: Bytes32 - logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM] - prev_randao: Bytes32 # 'difficulty' in the yellow paper - block_number: uint64 # 'number' in the yellow paper - gas_limit: uint64 - gas_used: uint64 - timestamp: uint64 - extra_data: ByteList[MAX_EXTRA_DATA_BYTES] - base_fee_per_gas: uint256 - # Extra payload fields - block_hash: Hash32 # Hash of execution block - transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD] - withdrawals: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD] - blob_gas_used: uint64 - excess_blob_gas: uint64 - withdraw_requests: List[ExecutionLayerWithdrawRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD] # [New in EIP-7251] -``` - -#### `ExecutionPayloadHeader` - -```python -class ExecutionPayloadHeader(Container): - # Execution block header fields - parent_hash: Hash32 - fee_recipient: ExecutionAddress - state_root: Bytes32 - receipts_root: Bytes32 - logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM] - prev_randao: Bytes32 - block_number: uint64 - gas_limit: uint64 - gas_used: uint64 - timestamp: uint64 - extra_data: ByteList[MAX_EXTRA_DATA_BYTES] - base_fee_per_gas: uint256 - # Extra payload fields - block_hash: Hash32 # Hash of execution block - transactions_root: Root - withdrawals_root: Root - blob_gas_used: uint64 - excess_blob_gas: uint64 - withdraw_requests_root: Root # [New in EIP-7251] -``` - -## Helpers - -### Predicates - -#### Updated `is_eligible_for_activation_queue` - -```python -def is_eligible_for_activation_queue(validator: Validator) -> bool: - """ - Check if ``validator`` is eligible to be placed into the activation queue. - """ - return ( - validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH - and validator.effective_balance >= MIN_ACTIVATION_BALANCE # [Modified in EIP7251] - ) -``` - -#### New `is_compounding_withdrawal_credential` - -```python -def is_compounding_withdrawal_credential(withdrawal_credentials: Bytes32) -> bool: - return withdrawal_credentials[:1] == COMPOUNDING_WITHDRAWAL_PREFIX -``` - -#### New `has_compounding_withdrawal_credential` - -```python -def has_compounding_withdrawal_credential(validator: Validator) -> bool: - """ - Check if ``validator`` has an 0x02 prefixed "compounding" withdrawal credential. - """ - return is_compounding_withdrawal_credential(validator.withdrawal_credentials) -``` - -#### New `has_execution_withdrawal_credential` - -```python -def has_execution_withdrawal_credential(validator: Validator) -> bool: - """ - Check if ``validator`` has a 0x01 or 0x02 prefixed withdrawal credential. - """ - return has_compounding_withdrawal_credential(validator) or has_eth1_withdrawal_credential(validator) -``` - -#### Updated `is_fully_withdrawable_validator` - -```python -def is_fully_withdrawable_validator(validator: Validator, balance: Gwei, epoch: Epoch) -> bool: - """ - Check if ``validator`` is fully withdrawable. - """ - return ( - has_execution_withdrawal_credential(validator) # [Modified in EIP7251] - and validator.withdrawable_epoch <= epoch - and balance > 0 - ) -``` - -#### Updated `is_partially_withdrawable_validator` - -```python -def is_partially_withdrawable_validator(validator: Validator, balance: Gwei) -> bool: - """ - Check if ``validator`` is partially withdrawable. - """ - max_effective_balance = get_validator_max_effective_balance(validator) - has_max_effective_balance = validator.effective_balance == max_effective_balance # [Modified in EIP7251] - has_excess_balance = balance > max_effective_balance # [Modified in EIP7251] - return ( - has_execution_withdrawal_credential(validator) # [Modified in EIP7251] - and has_max_effective_balance - and has_excess_balance - ) -``` - -### Beacon state accessors - -#### New `get_validator_max_effective_balance` - -```python -def get_validator_max_effective_balance(validator: Validator) -> Gwei: - """ - Get max effective balance for ``validator``. - """ - if has_compounding_withdrawal_credential(validator): - return MAX_EFFECTIVE_BALANCE_EIP7251 - else: - return MIN_ACTIVATION_BALANCE -``` - -#### New `get_churn_limit` - -```python -def get_churn_limit(state: BeaconState) -> Gwei: - """ - Return the churn limit for the current epoch. - """ - churn = max( - MIN_PER_EPOCH_CHURN_LIMIT_EIP7251, - get_total_active_balance(state) // CHURN_LIMIT_QUOTIENT - ) - return churn - churn % EFFECTIVE_BALANCE_INCREMENT -``` - -#### New `get_activation_exit_churn_limit` - -```python -def get_activation_exit_churn_limit(state: BeaconState) -> Gwei: - """ - Return the churn limit for the current epoch dedicated to activations and exits. - """ - return min(MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT, get_churn_limit(state)) -``` - -#### New `get_consolidation_churn_limit` - -```python -def get_consolidation_churn_limit(state: BeaconState) -> Gwei: - return get_churn_limit(state) - get_activation_exit_churn_limit(state) -``` - -#### New `get_active_balance` - -```python -def get_active_balance(state: BeaconState, validator_index: ValidatorIndex) -> Gwei: - max_effective_balance = get_validator_max_effective_balance(state.validators[validator_index]) - return min(state.balances[validator_index], max_effective_balance) -``` - -#### New `get_pending_balance_to_withdraw` - -```python -def get_pending_balance_to_withdraw(state: BeaconState, validator_index: ValidatorIndex) -> Gwei: - return sum( - withdrawal.amount for withdrawal in state.pending_partial_withdrawals if withdrawal.index == validator_index) -``` - -### Beacon state mutators - -#### Updated `initiate_validator_exit` - -```python -def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None: - """ - Initiate the exit of the validator with index ``index``. - """ - # Return if validator already initiated exit - validator = state.validators[index] - if validator.exit_epoch != FAR_FUTURE_EPOCH: - return - - # Compute exit queue epoch [Modified in EIP 7251] - exit_queue_epoch = compute_exit_epoch_and_update_churn(state, validator.effective_balance) - - # Set validator exit epoch and withdrawable epoch - validator.exit_epoch = exit_queue_epoch - validator.withdrawable_epoch = Epoch(validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY) -``` - -#### New `switch_to_compounding_validator` - -```python -def switch_to_compounding_validator(state: BeaconState, index: ValidatorIndex) -> None: - validator = state.validators[index] - if has_eth1_withdrawal_credential(validator): - validator.withdrawal_credentials = COMPOUNDING_WITHDRAWAL_PREFIX + validator.withdrawal_credentials[1:] - queue_excess_active_balance(state, index) -``` - -#### New `queue_excess_active_balance` - -```python -def queue_excess_active_balance(state: BeaconState, index: ValidatorIndex) -> None: - balance = state.balances[index] - if balance > MIN_ACTIVATION_BALANCE: - excess_balance = balance - MIN_ACTIVATION_BALANCE - state.balances[index] = MIN_ACTIVATION_BALANCE - state.pending_balance_deposits.append( - PendingBalanceDeposit(index=index, amount=excess_balance) - ) -``` - -#### New `compute_exit_epoch_and_update_churn` - -```python -def compute_exit_epoch_and_update_churn(state: BeaconState, exit_balance: Gwei) -> Epoch: - earliest_exit_epoch = compute_activation_exit_epoch(get_current_epoch(state)) - per_epoch_churn = get_activation_exit_churn_limit(state) - # New epoch for exits. - if state.earliest_exit_epoch < earliest_exit_epoch: - state.earliest_exit_epoch = earliest_exit_epoch - state.exit_balance_to_consume = per_epoch_churn - - if exit_balance <= state.exit_balance_to_consume: - # Exit fits in the current earliest epoch. - state.exit_balance_to_consume -= exit_balance - else: - # Exit doesn't fit in the current earliest epoch. - balance_to_process = exit_balance - state.exit_balance_to_consume - additional_epochs, remainder = divmod(balance_to_process, per_epoch_churn) - state.earliest_exit_epoch += additional_epochs + 1 - state.exit_balance_to_consume = per_epoch_churn - remainder - - return state.earliest_exit_epoch -``` - -#### New `compute_consolidation_epoch_and_update_churn` - -```python -def compute_consolidation_epoch_and_update_churn(state: BeaconState, consolidation_balance: Gwei) -> Epoch: - earliest_consolidation_epoch = compute_activation_exit_epoch(get_current_epoch(state)) - per_epoch_consolidation_churn = get_consolidation_churn_limit(state) - # New epoch for consolidations. - if state.earliest_consolidation_epoch < earliest_consolidation_epoch: - state.earliest_consolidation_epoch = earliest_consolidation_epoch - state.consolidation_balance_to_consume = per_epoch_consolidation_churn - - if consolidation_balance <= state.consolidation_balance_to_consume: - # Consolidation fits in the current earliest consolidation epoch. - state.consolidation_balance_to_consume -= consolidation_balance - else: - # Consolidation doesn't fit in the current earliest epoch. - balance_to_process = consolidation_balance - state.consolidation_balance_to_consume - additional_epochs, remainder = divmod(balance_to_process, per_epoch_consolidation_churn) - state.earliest_consolidation_epoch += additional_epochs + 1 - state.consolidation_balance_to_consume = per_epoch_consolidation_churn - remainder - - return state.earliest_consolidation_epoch -``` - -#### Updated `slash_validator` - -```python -def slash_validator(state: BeaconState, - slashed_index: ValidatorIndex, - whistleblower_index: ValidatorIndex=None) -> None: - """ - Slash the validator with index ``slashed_index``. - """ - epoch = get_current_epoch(state) - initiate_validator_exit(state, slashed_index) - validator = state.validators[slashed_index] - validator.slashed = True - validator.withdrawable_epoch = max(validator.withdrawable_epoch, Epoch(epoch + EPOCHS_PER_SLASHINGS_VECTOR)) - state.slashings[epoch % EPOCHS_PER_SLASHINGS_VECTOR] += validator.effective_balance - slashing_penalty = validator.effective_balance // MIN_SLASHING_PENALTY_QUOTIENT_EIP7251 # [Modified in EIP7251] - decrease_balance(state, slashed_index, slashing_penalty) - - # Apply proposer and whistleblower rewards - proposer_index = get_beacon_proposer_index(state) - if whistleblower_index is None: - whistleblower_index = proposer_index - whistleblower_reward = Gwei( - validator.effective_balance // WHISTLEBLOWER_REWARD_QUOTIENT_EIP7251) # [Modified in EIP7251] - proposer_reward = Gwei(whistleblower_reward * PROPOSER_WEIGHT // WEIGHT_DENOMINATOR) - increase_balance(state, proposer_index, proposer_reward) - increase_balance(state, whistleblower_index, Gwei(whistleblower_reward - proposer_reward)) -``` - -## Beacon chain state transition function - -### Epoch processing - -#### Updated `process_epoch` -```python -def process_epoch(state: BeaconState) -> None: - process_justification_and_finalization(state) - process_inactivity_updates(state) - process_rewards_and_penalties(state) - process_registry_updates(state) # [Modified in EIP7251] - process_slashings(state) - process_eth1_data_reset(state) - process_pending_balance_deposits(state) # New in EIP7251 - process_pending_consolidations(state) # New in EIP7251 - process_effective_balance_updates(state) # [Modified in EIP7251] - process_slashings_reset(state) - process_randao_mixes_reset(state) - process_historical_summaries_update(state) - process_participation_flag_updates(state) - process_sync_committee_updates(state) -``` - -#### Updated `process_registry_updates` - -`process_registry_updates` uses the updated definition of `initiate_validator_exit` -and changes how the activation epochs are computed for eligible validators. - -```python -def process_registry_updates(state: BeaconState) -> None: - # Process activation eligibility and ejections - for index, validator in enumerate(state.validators): - if is_eligible_for_activation_queue(validator): - validator.activation_eligibility_epoch = get_current_epoch(state) + 1 - - if ( - is_active_validator(validator, get_current_epoch(state)) - and validator.effective_balance <= EJECTION_BALANCE - ): - initiate_validator_exit(state, ValidatorIndex(index)) - - # Activate all eligible validators - activation_epoch = compute_activation_exit_epoch(get_current_epoch(state)) - for validator in state.validators: - if is_eligible_for_activation(state, validator): - validator.activation_epoch = activation_epoch -``` - -#### New `process_pending_balance_deposits` - -```python -def process_pending_balance_deposits(state: BeaconState) -> None: - available_for_processing = state.deposit_balance_to_consume + get_activation_exit_churn_limit(state) - processed_amount = 0 - next_deposit_index = 0 - - for deposit in state.pending_balance_deposits: - if processed_amount + deposit.amount > available_for_processing: - break - increase_balance(state, deposit.index, deposit.amount) - processed_amount += deposit.amount - next_deposit_index += 1 - - state.pending_balance_deposits = state.pending_balance_deposits[next_deposit_index:] - - if len(state.pending_balance_deposits) == 0: - state.deposit_balance_to_consume = Gwei(0) - else: - state.deposit_balance_to_consume = available_for_processing - processed_amount -``` - -#### New `process_pending_consolidations` - -```python -def process_pending_consolidations(state: BeaconState) -> None: - next_pending_consolidation = 0 - for pending_consolidation in state.pending_consolidations: - source_validator = state.validators[pending_consolidation.source_index] - if source_validator.slashed: - next_pending_consolidation += 1 - continue - if source_validator.withdrawable_epoch > get_current_epoch(state): - break - - # Churn any target excess active balance of target and raise its max - switch_to_compounding_validator(state, pending_consolidation.target_index) - # Move active balance to target. Excess balance is withdrawable. - active_balance = get_active_balance(state, pending_consolidation.source_index) - decrease_balance(state, pending_consolidation.source_index, active_balance) - increase_balance(state, pending_consolidation.target_index, active_balance) - next_pending_consolidation += 1 - - state.pending_consolidations = state.pending_consolidations[next_pending_consolidation:] -``` - -#### Updated `process_effective_balance_updates` - -`process_effective_balance_updates` is updated with a new limit for the maximum effective balance. - -```python -def process_effective_balance_updates(state: BeaconState) -> None: - # Update effective balances with hysteresis - for index, validator in enumerate(state.validators): - balance = state.balances[index] - HYSTERESIS_INCREMENT = uint64(EFFECTIVE_BALANCE_INCREMENT // HYSTERESIS_QUOTIENT) - DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER - UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER - EFFECTIVE_BALANCE_LIMIT = ( - MAX_EFFECTIVE_BALANCE_EIP7251 if has_compounding_withdrawal_credential(validator) - else MIN_ACTIVATION_BALANCE - ) - - if ( - balance + DOWNWARD_THRESHOLD < validator.effective_balance - or validator.effective_balance + UPWARD_THRESHOLD < balance - ): - validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, EFFECTIVE_BALANCE_LIMIT) -``` - -### Block processing - -```python -def process_block(state: BeaconState, block: BeaconBlock) -> None: - process_block_header(state, block) - process_withdrawals(state, block.body.execution_payload) # [Modified in EIP7251] - process_execution_payload(state, block.body, EXECUTION_ENGINE) - process_randao(state, block.body) - process_eth1_data(state, block.body) - process_operations(state, block.body) # [Modified in EIP7251] - process_sync_aggregate(state, block.body.sync_aggregate) -``` - -##### Updated `get_expected_withdrawals` - -```python -def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal], uint64]: - epoch = get_current_epoch(state) - withdrawal_index = state.next_withdrawal_index - validator_index = state.next_withdrawal_validator_index - withdrawals: List[Withdrawal] = [] - - # [New in EIP7251] Consume pending partial withdrawals - for withdrawal in state.pending_partial_withdrawals: - if withdrawal.withdrawable_epoch > epoch or len(withdrawals) == MAX_PARTIAL_WITHDRAWALS_PER_PAYLOAD: - break - - validator = state.validators[withdrawal.index] - has_sufficient_effective_balance = validator.effective_balance >= MIN_ACTIVATION_BALANCE - has_excess_balance = state.balances[withdrawal.index] > MIN_ACTIVATION_BALANCE - if validator.exit_epoch == FAR_FUTURE_EPOCH and has_sufficient_effective_balance and has_excess_balance: - withdrawable_balance = min(state.balances[withdrawal.index] - MIN_ACTIVATION_BALANCE, withdrawal.amount) - withdrawals.append(Withdrawal( - index=withdrawal_index, - validator_index=withdrawal.index, - address=ExecutionAddress(validator.withdrawal_credentials[12:]), - amount=withdrawable_balance, - )) - withdrawal_index += WithdrawalIndex(1) - - partial_withdrawals_count = len(withdrawals) - # END: Consume pending partial withdrawals - - # Sweep for remaining. - bound = min(len(state.validators), MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP) - for _ in range(bound): - validator = state.validators[validator_index] - balance = state.balances[validator_index] - if is_fully_withdrawable_validator(validator, balance, epoch): - withdrawals.append(Withdrawal( - index=withdrawal_index, - validator_index=validator_index, - address=ExecutionAddress(validator.withdrawal_credentials[12:]), - amount=balance, - )) - withdrawal_index += WithdrawalIndex(1) - elif is_partially_withdrawable_validator(validator, balance): - withdrawals.append(Withdrawal( - index=withdrawal_index, - validator_index=validator_index, - address=ExecutionAddress(validator.withdrawal_credentials[12:]), - amount=balance - get_validator_max_effective_balance(validator), # [Modified in EIP7251] - )) - withdrawal_index += WithdrawalIndex(1) - if len(withdrawals) == MAX_WITHDRAWALS_PER_PAYLOAD: - break - validator_index = ValidatorIndex((validator_index + 1) % len(state.validators)) - return withdrawals, partial_withdrawals_count -``` - -##### Updated `process_withdrawals` - -```python -def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None: - expected_withdrawals, partial_withdrawals_count = get_expected_withdrawals(state) # [Modified in EIP7251] - - assert len(payload.withdrawals) == len(expected_withdrawals) - - for expected_withdrawal, withdrawal in zip(expected_withdrawals, payload.withdrawals): - assert withdrawal == expected_withdrawal - decrease_balance(state, withdrawal.validator_index, withdrawal.amount) - - # [New in EIP7251] update pending partial withdrawals - state.pending_partial_withdrawals = state.pending_partial_withdrawals[partial_withdrawals_count:] - - # Update the next withdrawal index if this block contained withdrawals - if len(expected_withdrawals) != 0: - latest_withdrawal = expected_withdrawals[-1] - state.next_withdrawal_index = WithdrawalIndex(latest_withdrawal.index + 1) - - # Update the next validator index to start the next withdrawal sweep - if len(expected_withdrawals) == MAX_WITHDRAWALS_PER_PAYLOAD: - # Next sweep starts after the latest withdrawal's validator index - next_validator_index = ValidatorIndex((expected_withdrawals[-1].validator_index + 1) % len(state.validators)) - state.next_withdrawal_validator_index = next_validator_index - else: - # Advance sweep by the max length of the sweep if there was not a full set of withdrawals - next_index = state.next_withdrawal_validator_index + MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP - next_validator_index = ValidatorIndex(next_index % len(state.validators)) - state.next_withdrawal_validator_index = next_validator_index -``` - -#### Operations - -##### Updated `process_operations` - -```python -def process_operations(state: BeaconState, body: BeaconBlockBody) -> None: - # Verify that outstanding deposits are processed up to the maximum number of deposits - assert len(body.deposits) == min(MAX_DEPOSITS, state.eth1_data.deposit_count - state.eth1_deposit_index) - - def for_ops(operations: Sequence[Any], fn: Callable[[BeaconState, Any], None]) -> None: - for operation in operations: - fn(state, operation) - - for_ops(body.proposer_slashings, process_proposer_slashing) - for_ops(body.attester_slashings, process_attester_slashing) - for_ops(body.attestations, process_attestation) - for_ops(body.deposits, process_deposit) # [Modified in EIP7251] - for_ops(body.voluntary_exits, process_voluntary_exit) # [Modified in EIP7251] - for_ops(body.bls_to_execution_changes, process_bls_to_execution_change) - for_ops(body.execution_payload.withdraw_requests, process_execution_layer_withdraw_request) # [New in EIP7251] - for_ops(body.consolidations, process_consolidation) # [New in EIP7251] -``` - -##### Deposits - -###### Updated `apply_deposit` - -*NOTE*: `process_deposit` is updated with a new definition of `apply_deposit`. - -```python -def apply_deposit(state: BeaconState, - pubkey: BLSPubkey, - withdrawal_credentials: Bytes32, - amount: uint64, - signature: BLSSignature) -> None: - validator_pubkeys = [v.pubkey for v in state.validators] - if pubkey not in validator_pubkeys: - # Verify the deposit signature (proof of possession) which is not checked by the deposit contract - if is_valid_deposit_signature(pubkey, withdrawal_credentials, amount, signature): - add_validator_to_registry(state, pubkey, withdrawal_credentials, amount) - else: - # Increase balance by deposit amount - index = ValidatorIndex(validator_pubkeys.index(pubkey)) - state.pending_balance_deposits.append( - PendingBalanceDeposit(index=index, amount=amount)) # [Modified in EIP-7251] - # Check if valid deposit switch to compounding credentials - if ( - is_compounding_withdrawal_credential(withdrawal_credentials) - and has_eth1_withdrawal_credential(state.validators[index]) - and is_valid_deposit_signature(pubkey, withdrawal_credentials, amount, signature) - ): - switch_to_compounding_validator(state, index) - -``` - -###### New `is_valid_deposit_signature` - -```python -def is_valid_deposit_signature(pubkey: BLSPubkey, - withdrawal_credentials: Bytes32, - amount: uint64, - signature: BLSSignature) -> bool: - deposit_message = DepositMessage( - pubkey=pubkey, - withdrawal_credentials=withdrawal_credentials, - amount=amount, - ) - domain = compute_domain(DOMAIN_DEPOSIT) # Fork-agnostic domain since deposits are valid across forks - signing_root = compute_signing_root(deposit_message, domain) - return bls.Verify(pubkey, signing_root, signature) -``` - -###### Modified `add_validator_to_registry` - -```python -def add_validator_to_registry(state: BeaconState, - pubkey: BLSPubkey, - withdrawal_credentials: Bytes32, - amount: uint64) -> None: - index = get_index_for_new_validator(state) - validator = get_validator_from_deposit(pubkey, withdrawal_credentials) - set_or_append_list(state.validators, index, validator) - set_or_append_list(state.balances, index, 0) # [Modified in EIP7251] - set_or_append_list(state.previous_epoch_participation, index, ParticipationFlags(0b0000_0000)) - set_or_append_list(state.current_epoch_participation, index, ParticipationFlags(0b0000_0000)) - set_or_append_list(state.inactivity_scores, index, uint64(0)) - state.pending_balance_deposits.append(PendingBalanceDeposit(index=index, amount=amount)) # [New in EIP7251] -``` - -###### Updated `get_validator_from_deposit` - -```python -def get_validator_from_deposit(pubkey: BLSPubkey, withdrawal_credentials: Bytes32) -> Validator: - return Validator( - pubkey=pubkey, - withdrawal_credentials=withdrawal_credentials, - activation_eligibility_epoch=FAR_FUTURE_EPOCH, - activation_epoch=FAR_FUTURE_EPOCH, - exit_epoch=FAR_FUTURE_EPOCH, - withdrawable_epoch=FAR_FUTURE_EPOCH, - effective_balance=0, # [Modified in EIP7251] - ) -``` - -##### Withdrawals - -###### New `process_execution_layer_withdraw_request` - -```python -def process_execution_layer_withdraw_request( - state: BeaconState, - execution_layer_withdraw_request: ExecutionLayerWithdrawRequest -) -> None: - amount = execution_layer_withdraw_request.amount - is_full_exit_request = amount == FULL_EXIT_REQUEST_AMOUNT - - # If partial withdrawal queue is full, only full exits are processed - if len(state.pending_partial_withdrawals) >= PENDING_PARTIAL_WITHDRAWALS_LIMIT and not is_full_exit_request: - return - - validator_pubkeys = [v.pubkey for v in state.validators] - index = ValidatorIndex(validator_pubkeys.index(execution_layer_withdraw_request.validator_pubkey)) - validator = state.validators[index] - - # Same conditions as in EIP-7002 - if not ( - has_execution_withdrawal_credential(validator) - # Verify withdrawal credentials - and validator.withdrawal_credentials[12:] == execution_layer_withdraw_request.source_address - # Verify the validator is active - and is_active_validator(validator, get_current_epoch(state)) - # Verify exit has not been initiated, and slashed - and validator.exit_epoch == FAR_FUTURE_EPOCH - # Verify the validator has been active long enough - and get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD - ): - return - - pending_balance_to_withdraw = get_pending_balance_to_withdraw(state, index) - - if is_full_exit_request: - # Only exit validator if it has no pending withdrawals in the queue - if pending_balance_to_withdraw == 0: - initiate_validator_exit(state, index) - - return - - has_sufficient_effective_balance = validator.effective_balance >= MIN_ACTIVATION_BALANCE - has_excess_balance = state.balances[index] > MIN_ACTIVATION_BALANCE + pending_balance_to_withdraw - - # Only allow partial withdrawals with compounding withdrawal credentials - if has_compounding_withdrawal_credential(validator) and has_sufficient_effective_balance and has_excess_balance: - to_withdraw = min( - state.balances[index] - MIN_ACTIVATION_BALANCE - pending_balance_to_withdraw, - amount - ) - exit_queue_epoch = compute_exit_epoch_and_update_churn(state, to_withdraw) - withdrawable_epoch = Epoch(exit_queue_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY) - state.pending_partial_withdrawals.append(PendingPartialWithdrawal( - index=index, - amount=to_withdraw, - withdrawable_epoch=withdrawable_epoch, - )) -``` - -##### Consolidations - -###### New `process_consolidation` - -```python -def process_consolidation(state: BeaconState, signed_consolidation: SignedConsolidation) -> None: - # If the pending consolidations queue is full, no consolidations are allowed in the block - assert len(state.pending_consolidations) < PENDING_CONSOLIDATIONS_LIMIT - # If there is too little available consolidation churn limit, no consolidations are allowed in the block - assert get_consolidation_churn_limit(state) > MIN_ACTIVATION_BALANCE - consolidation = signed_consolidation.message - # Verify that source != target, so a consolidation cannot be used as an exit. - assert consolidation.source_index != consolidation.target_index - - source_validator = state.validators[consolidation.source_index] - target_validator = state.validators[consolidation.target_index] - # Verify the source and the target are active - current_epoch = get_current_epoch(state) - assert is_active_validator(source_validator, current_epoch) - assert is_active_validator(target_validator, current_epoch) - # Verify exits for source and target have not been initiated - assert source_validator.exit_epoch == FAR_FUTURE_EPOCH - assert target_validator.exit_epoch == FAR_FUTURE_EPOCH - # Consolidations must specify an epoch when they become valid; they are not valid before then - assert current_epoch >= consolidation.epoch - - # Verify the source and the target have Execution layer withdrawal credentials - assert has_execution_withdrawal_credential(source_validator) - assert has_execution_withdrawal_credential(target_validator) - # Verify the same withdrawal address - assert source_validator.withdrawal_credentials[12:] == target_validator.withdrawal_credentials[12:] - - # Verify consolidation is signed by the source and the target - domain = compute_domain(DOMAIN_CONSOLIDATION, genesis_validators_root=state.genesis_validators_root) - signing_root = compute_signing_root(consolidation, domain) - pubkeys = [source_validator.pubkey, target_validator.pubkey] - assert bls.FastAggregateVerify(pubkeys, signing_root, signed_consolidation.signature) - - # Initiate source validator exit and append pending consolidation - source_validator.exit_epoch = compute_consolidation_epoch_and_update_churn( - state, source_validator.effective_balance) - source_validator.withdrawable_epoch = Epoch( - source_validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY - ) - state.pending_consolidations.append(PendingConsolidation( - source_index=consolidation.source_index, - target_index=consolidation.target_index - )) -``` - -##### Voluntary exits - -###### Updated `process_voluntary_exit` - -```python -def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None: - voluntary_exit = signed_voluntary_exit.message - validator = state.validators[voluntary_exit.validator_index] - # Verify the validator is active - assert is_active_validator(validator, get_current_epoch(state)) - # Verify exit has not been initiated - assert validator.exit_epoch == FAR_FUTURE_EPOCH - # Exits must specify an epoch when they become valid; they are not valid before then - assert get_current_epoch(state) >= voluntary_exit.epoch - # Verify the validator has been active long enough - assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD - # [New in EIP-7251] Only exit validator if it has no pending withdrawals in the queue - assert get_pending_balance_to_withdraw(state, voluntary_exit.validator_index) == 0 # [New in EIP7251] - # Verify signature - domain = compute_domain(DOMAIN_VOLUNTARY_EXIT, CAPELLA_FORK_VERSION, state.genesis_validators_root) - signing_root = compute_signing_root(voluntary_exit, domain) - assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature) - # Initiate exit - initiate_validator_exit(state, voluntary_exit.validator_index) -``` - -## Testing - -*Note*: The function `initialize_beacon_state_from_eth1` is modified for pure EIP-7251 testing only. - -```python -def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32, - eth1_timestamp: uint64, - deposits: Sequence[Deposit], - execution_payload_header: ExecutionPayloadHeader=ExecutionPayloadHeader() - ) -> BeaconState: - fork = Fork( - previous_version=EIP7251_FORK_VERSION, # [Modified in EIP-7251] for testing only - current_version=EIP7251_FORK_VERSION, # [Modified in EIP-7251] - epoch=GENESIS_EPOCH, - ) - state = BeaconState( - genesis_time=eth1_timestamp + GENESIS_DELAY, - fork=fork, - eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=uint64(len(deposits))), - latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), - randao_mixes=[eth1_block_hash] * EPOCHS_PER_HISTORICAL_VECTOR, # Seed RANDAO with Eth1 entropy - ) - - # Process deposits - leaves = list(map(lambda deposit: deposit.data, deposits)) - for index, deposit in enumerate(deposits): - deposit_data_list = List[DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH](*leaves[:index + 1]) - state.eth1_data.deposit_root = hash_tree_root(deposit_data_list) - process_deposit(state, deposit) - - # Process deposit balance updates - for deposit in state.pending_balance_deposits: - increase_balance(state, deposit.index, deposit.amount) - state.pending_balance_deposits = [] - - # Process activations - for index, validator in enumerate(state.validators): - balance = state.balances[index] - validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE) - if validator.effective_balance == MAX_EFFECTIVE_BALANCE: - validator.activation_eligibility_epoch = GENESIS_EPOCH - validator.activation_epoch = GENESIS_EPOCH - - # Set genesis validators root for domain separation and chain versioning - state.genesis_validators_root = hash_tree_root(state.validators) - - # Fill in sync committees - # Note: A duplicate committee is assigned for the current and next committee at genesis - state.current_sync_committee = get_next_sync_committee(state) - state.next_sync_committee = get_next_sync_committee(state) - - # Initialize the execution payload header - # If empty, will initialize a chain that has not yet gone through the Merge transition - state.latest_execution_payload_header = execution_payload_header - - return state -``` diff --git a/tests/core/pyspec/eth2spec/test/capella/block_processing/test_process_deposit.py b/tests/core/pyspec/eth2spec/test/capella/block_processing/test_process_deposit.py index 139ced515..4f2176ca2 100644 --- a/tests/core/pyspec/eth2spec/test/capella/block_processing/test_process_deposit.py +++ b/tests/core/pyspec/eth2spec/test/capella/block_processing/test_process_deposit.py @@ -2,7 +2,7 @@ from eth2spec.test.context import ( spec_state_test, with_capella_and_later, ) -from eth2spec.test.helpers.forks import is_post_eip7251 +from eth2spec.test.helpers.forks import is_post_electra from eth2spec.test.helpers.state import next_epoch_via_block from eth2spec.test.helpers.deposits import ( prepare_state_and_deposit, @@ -31,7 +31,7 @@ def test_success_top_up_to_withdrawn_validator(spec, state): yield from run_deposit_processing(spec, state, deposit, validator_index) - if is_post_eip7251(spec): + if is_post_electra(spec): pending_balance_deposits_len = len(state.pending_balance_deposits) pending_balance_deposit = state.pending_balance_deposits[pending_balance_deposits_len - 1] assert pending_balance_deposit.amount == amount @@ -44,7 +44,7 @@ def test_success_top_up_to_withdrawn_validator(spec, state): balance = state.balances[validator_index] current_epoch = spec.get_current_epoch(state) - if is_post_eip7251(spec): + if is_post_electra(spec): has_execution_withdrawal = spec.has_execution_withdrawal_credential(validator) is_withdrawable = validator.withdrawable_epoch <= current_epoch has_non_zero_balance = pending_balance_deposit.amount > 0 diff --git a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py index ef1f803a5..6da7b3d41 100644 --- a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py @@ -1,5 +1,5 @@ from eth2spec.test.helpers.constants import MINIMAL -from eth2spec.test.helpers.forks import is_post_eip7251 +from eth2spec.test.helpers.forks import is_post_electra from eth2spec.test.context import ( with_capella_and_later, spec_state_test, @@ -359,7 +359,7 @@ def test_top_up_and_partial_withdrawable_validator(spec, state): signed_block = state_transition_and_sign_block(spec, state, block) - # ensure we go through an epoch transition, to account for post-EIP-7251 behavior + # ensure we go through an epoch transition, to account for post-electra behavior block_in_next_epoch = build_empty_block(spec, state, slot=state.slot + spec.SLOTS_PER_EPOCH) signed_block_in_next_epoch = state_transition_and_sign_block(spec, state, block_in_next_epoch) @@ -402,7 +402,7 @@ def test_top_up_to_fully_withdrawn_validator(spec, state): signed_block_1 = state_transition_and_sign_block(spec, state, block) balance = state.balances[validator_index] - if is_post_eip7251(spec): + if is_post_electra(spec): balance += state.pending_balance_deposits[0].amount assert spec.is_fully_withdrawable_validator( diff --git a/tests/core/pyspec/eth2spec/test/deneb/epoch_processing/test_process_registry_updates.py b/tests/core/pyspec/eth2spec/test/deneb/epoch_processing/test_process_registry_updates.py index c17f12785..9d5a2e5d9 100644 --- a/tests/core/pyspec/eth2spec/test/deneb/epoch_processing/test_process_registry_updates.py +++ b/tests/core/pyspec/eth2spec/test/deneb/epoch_processing/test_process_registry_updates.py @@ -1,5 +1,5 @@ from eth2spec.test.helpers.keys import pubkeys -from eth2spec.test.helpers.forks import is_post_eip7251 +from eth2spec.test.helpers.forks import is_post_electra from eth2spec.test.helpers.constants import MINIMAL from eth2spec.test.context import ( with_deneb_and_later, @@ -50,7 +50,7 @@ def run_test_activation_churn_limit(spec, state): index = validator_count_0 + i # NOTE: activations are gated different after EIP-7251 # all eligible validators have been activated - if index < validator_count_0 + churn_limit_0 or is_post_eip7251(spec): + if index < validator_count_0 + churn_limit_0 or is_post_electra(spec): # The eligible validators within the activation churn limit should have been activated assert state.validators[index].activation_epoch < spec.FAR_FUTURE_EPOCH else: diff --git a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/__init__.py b/tests/core/pyspec/eth2spec/test/eip7251/block_processing/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_voluntary_exit.py b/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_voluntary_exit.py deleted file mode 100644 index ba28f34ec..000000000 --- a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_voluntary_exit.py +++ /dev/null @@ -1,441 +0,0 @@ -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) diff --git a/tests/core/pyspec/eth2spec/test/eip7251/unittests/__init__.py b/tests/core/pyspec/eth2spec/test/eip7251/unittests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_consolidation.py b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_consolidation.py similarity index 99% rename from tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_consolidation.py rename to tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_consolidation.py index 31b5dde1f..9af262f60 100644 --- a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_consolidation.py +++ b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_consolidation.py @@ -118,7 +118,7 @@ def test_basic_consolidation_in_new_consolidation_epoch(spec, state): 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_custom_state( balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, @@ -166,7 +166,7 @@ def test_basic_consolidation_with_preexisting_churn(spec, state): 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_custom_state( balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, @@ -218,7 +218,7 @@ def test_basic_consolidation_with_insufficient_preexisting_churn(spec, state): 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_custom_state( balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit, @@ -701,7 +701,7 @@ def test_invalid_exceed_pending_consolidations_limit(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_invalid_not_enough_consolidation_churn_available(spec, state): state.validators = state.validators[0:2] diff --git a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_deposit.py b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_deposit.py similarity index 84% rename from tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_deposit.py rename to tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_deposit.py index 196b61e77..80faad551 100644 --- a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_deposit.py +++ b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_deposit.py @@ -1,8 +1,8 @@ from eth2spec.test.helpers.deposits import ( build_deposit, prepare_state_and_deposit, - run_deposit_processing_electra, - run_deposit_processing_electra_with_specific_fork_version, + run_deposit_processing, + run_deposit_processing_with_specific_fork_version, sign_deposit_data, ) from eth2spec.test.helpers.keys import privkeys, pubkeys @@ -23,7 +23,7 @@ def test_new_deposit_under_min_activation_balance(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) @with_electra_and_later @@ -33,7 +33,7 @@ def test_new_deposit_min(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) @with_electra_and_later @@ -43,7 +43,7 @@ def test_new_deposit_between_min_and_max(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) @with_electra_and_later @@ -54,7 +54,7 @@ def test_new_deposit_max(spec, state): # 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) @with_electra_and_later @@ -64,7 +64,7 @@ def test_new_deposit_over_max(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) # @with_electra_and_later @@ -77,7 +77,7 @@ def test_new_deposit_over_max(spec, state): # 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) +# yield from run_deposit_processing(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 @@ -91,7 +91,7 @@ def test_correct_sig_but_forked_state(spec, state): # 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) @with_electra_and_later @@ -102,7 +102,7 @@ def test_incorrect_sig_new_deposit(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit, validator_index, effective=False) @with_electra_and_later @@ -115,7 +115,7 @@ def test_top_up__max_effective_balance(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) assert state.validators[validator_index].effective_balance == spec.MAX_EFFECTIVE_BALANCE @@ -132,7 +132,7 @@ def test_top_up__less_effective_balance(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) # unchanged effective balance assert state.validators[validator_index].effective_balance == initial_effective_balance @@ -150,7 +150,7 @@ def test_top_up__zero_balance(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) # unchanged effective balance assert state.validators[validator_index].effective_balance == initial_effective_balance @@ -165,7 +165,7 @@ def test_incorrect_sig_top_up(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) @with_electra_and_later @@ -183,7 +183,7 @@ def test_incorrect_withdrawal_credentials_top_up(spec, state): ) # inconsistent withdrawal credentials, in top-ups, are allowed! - yield from run_deposit_processing_electra(spec, state, deposit, validator_index) + yield from run_deposit_processing(spec, state, deposit, validator_index) @with_electra_and_later @@ -224,7 +224,7 @@ def test_invalid_wrong_deposit_for_deposit_count(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit_2, index_2, valid=False) @with_electra_and_later @@ -239,7 +239,7 @@ def test_invalid_bad_merkle_proof(spec, state): sign_deposit_data(spec, deposit.data, privkeys[validator_index]) - yield from run_deposit_processing_electra(spec, state, deposit, validator_index, valid=False) + yield from run_deposit_processing(spec, state, deposit, validator_index, valid=False) @with_electra_and_later @@ -253,7 +253,7 @@ def test_key_validate_invalid_subgroup(spec, state): 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) + yield from run_deposit_processing(spec, state, deposit, validator_index) @with_electra_and_later @@ -269,14 +269,14 @@ def test_key_validate_invalid_decompression(spec, state): 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) + yield from run_deposit_processing(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( + yield from run_deposit_processing_with_specific_fork_version( spec, state, fork_version=spec.Version('0xAaBbCcDd'), diff --git a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_execution_layer_withdraw_request.py b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_execution_layer_withdraw_request.py similarity index 98% rename from tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_execution_layer_withdraw_request.py rename to tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_execution_layer_withdraw_request.py index 065e5eab1..801ba7ffa 100644 --- a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_execution_layer_withdraw_request.py +++ b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_execution_layer_withdraw_request.py @@ -44,7 +44,7 @@ def test_basic_exit(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_basic_exit_with_compounding_credentials(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit @@ -66,7 +66,7 @@ def test_basic_exit_with_compounding_credentials(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets([MINIMAL], "need full partial withdrawal queue") def test_basic_exit_with_full_partial_withdrawal_queue(spec, state): @@ -243,7 +243,7 @@ def test_basic_partial_withdrawal_request(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets([MINIMAL]) def test_basic_partial_withdrawal_request_higher_excess_balance(spec, state): @@ -275,7 +275,7 @@ def test_basic_partial_withdrawal_request_higher_excess_balance(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets([MINIMAL]) def test_basic_partial_withdrawal_request_lower_than_excess_balance(spec, state): @@ -308,7 +308,7 @@ def test_basic_partial_withdrawal_request_lower_than_excess_balance(spec, state) ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets([MINIMAL]) def test_partial_withdrawal_request_with_pending_withdrawals(spec, state): @@ -347,7 +347,7 @@ def test_partial_withdrawal_request_with_pending_withdrawals(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets([MINIMAL]) def test_partial_withdrawal_request_with_pending_withdrawals_and_high_amount( @@ -378,7 +378,7 @@ def test_partial_withdrawal_request_with_pending_withdrawals_and_high_amount( ) # Set balance so that the validator still has excess balance even with the pending withdrawals - state.balances[validator_index] = spec.MAX_EFFECTIVE_BALANCE_EIP7251 + state.balances[validator_index] = spec.MAX_EFFECTIVE_BALANCE_ELECTRA yield from run_execution_layer_withdraw_request_processing( spec, @@ -387,7 +387,7 @@ def test_partial_withdrawal_request_with_pending_withdrawals_and_high_amount( ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets([MINIMAL]) def test_partial_withdrawal_request_with_high_balance(spec, state): @@ -396,10 +396,10 @@ def test_partial_withdrawal_request_with_high_balance(spec, state): validator_index = spec.get_active_validator_indices(state, current_epoch)[0] validator_pubkey = state.validators[validator_index].pubkey address = b"\x22" * 20 - amount = spec.MAX_EFFECTIVE_BALANCE_EIP7251 - state.balances[validator_index] = 3 * spec.MAX_EFFECTIVE_BALANCE_EIP7251 + amount = spec.MAX_EFFECTIVE_BALANCE_ELECTRA + state.balances[validator_index] = 3 * spec.MAX_EFFECTIVE_BALANCE_ELECTRA state.validators[validator_index].effective_balance = ( - spec.MAX_EFFECTIVE_BALANCE_EIP7251 + spec.MAX_EFFECTIVE_BALANCE_ELECTRA ) set_compounding_withdrawal_credential(spec, state, validator_index, address=address) @@ -424,7 +424,7 @@ def test_partial_withdrawal_request_with_high_balance(spec, state): assert state.earliest_exit_epoch == exit_epoch -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets([MINIMAL]) def test_partial_withdrawal_request_with_high_amount(spec, state): @@ -457,7 +457,7 @@ def test_partial_withdrawal_request_with_high_amount(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets([MINIMAL]) def test_partial_withdrawal_request_with_low_amount(spec, state): @@ -492,7 +492,7 @@ def test_partial_withdrawal_request_with_low_amount(spec, state): # No-op partial withdrawal tests -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets([MINIMAL], "need full partial withdrawal queue") def test_partial_withdrawal_queue_full(spec, state): @@ -523,7 +523,7 @@ def test_partial_withdrawal_queue_full(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_no_compounding_credentials(spec, state): state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH @@ -552,7 +552,7 @@ def test_no_compounding_credentials(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_no_excess_balance(spec, state): state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH @@ -574,7 +574,7 @@ def test_no_excess_balance(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_pending_withdrawals_consume_all_excess_balance(spec, state): state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH @@ -604,7 +604,7 @@ def test_pending_withdrawals_consume_all_excess_balance(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_insufficient_effective_balance(spec, state): state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH @@ -633,7 +633,7 @@ def test_insufficient_effective_balance(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_partial_withdrawal_incorrect_source_address(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit @@ -659,7 +659,7 @@ def test_partial_withdrawal_incorrect_source_address(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_partial_withdrawal_incorrect_withdrawal_credential_prefix(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit @@ -688,7 +688,7 @@ def test_partial_withdrawal_incorrect_withdrawal_credential_prefix(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_partial_withdrawal_on_exit_initiated_validator(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit @@ -714,7 +714,7 @@ def test_partial_withdrawal_on_exit_initiated_validator(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_partial_withdrawal_activation_epoch_less_than_shard_committee_period( spec, state diff --git a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_voluntary_exit.py b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_voluntary_exit.py similarity index 98% rename from tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_voluntary_exit.py rename to tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_voluntary_exit.py index d3eee4ee4..752af1e60 100644 --- a/tests/core/pyspec/eth2spec/test/eip7251/block_processing/test_process_voluntary_exit.py +++ b/tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_voluntary_exit.py @@ -1,7 +1,7 @@ from eth2spec.test.helpers.constants import MAINNET from eth2spec.test.context import ( spec_state_test, - with_eip7251_and_later, + with_electra_and_later, with_presets, ) from eth2spec.test.helpers.keys import pubkey_to_privkey @@ -15,7 +15,7 @@ from eth2spec.test.helpers.voluntary_exits import ( # ******************** -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_min_balance_exit(spec, state): state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH @@ -51,7 +51,7 @@ def test_min_balance_exit(spec, state): assert state.earliest_exit_epoch == expected_exit_epoch -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_min_balance_exits_up_to_churn(spec, state): state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH @@ -104,7 +104,7 @@ def test_min_balance_exits_up_to_churn(spec, state): assert state.earliest_exit_epoch == expected_exit_epoch -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_min_balance_exits_above_churn(spec, state): state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH @@ -156,7 +156,7 @@ def test_min_balance_exits_above_churn(spec, state): assert state.earliest_exit_epoch == expected_exit_epoch + 1 -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets( [MAINNET], @@ -168,7 +168,7 @@ def test_max_balance_exit(spec, state): churn_limit = spec.get_activation_exit_churn_limit(state) validator_index = spec.get_active_validator_indices(state, current_epoch)[0] # Set validator effective balance to 2048 ETH - to_exit = spec.MAX_EFFECTIVE_BALANCE_EIP7251 + to_exit = spec.MAX_EFFECTIVE_BALANCE_ELECTRA state.validators[validator_index].effective_balance = to_exit privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] @@ -200,7 +200,7 @@ def test_max_balance_exit(spec, state): assert state.earliest_exit_epoch == expected_exit_epoch -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets( [MAINNET], @@ -241,7 +241,7 @@ def test_exit_with_balance_equal_to_churn_limit(spec, state): assert state.earliest_exit_epoch == expected_exit_epoch -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets( [MAINNET], @@ -284,7 +284,7 @@ def test_exit_with_balance_multiple_of_churn_limit(spec, state): assert state.earliest_exit_epoch == expected_exit_epoch -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets( [MAINNET], @@ -331,7 +331,7 @@ def test_exit_existing_churn_and_churn_limit_balance(spec, state): assert state.earliest_exit_epoch == expected_exit_epoch -@with_eip7251_and_later +@with_electra_and_later @spec_state_test @with_presets( [MAINNET], @@ -382,7 +382,7 @@ def test_exit_existing_churn_and_balance_multiple_of_churn_limit(spec, state): assert state.earliest_exit_epoch == expected_exit_epoch -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_invalid_validator_has_pending_withdrawal(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit diff --git a/tests/core/pyspec/eth2spec/test/eip7251/epoch_processing/test_process_effective_balance_updates.py b/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_effective_balance_updates.py similarity index 79% rename from tests/core/pyspec/eth2spec/test/eip7251/epoch_processing/test_process_effective_balance_updates.py rename to tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_effective_balance_updates.py index 9e3a3f0ee..ddff61340 100644 --- a/tests/core/pyspec/eth2spec/test/eip7251/epoch_processing/test_process_effective_balance_updates.py +++ b/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_effective_balance_updates.py @@ -1,10 +1,10 @@ -from eth2spec.test.context import spec_state_test, with_eip7251_and_later +from eth2spec.test.context import spec_state_test, with_electra_and_later from eth2spec.test.phase0.epoch_processing.test_process_effective_balance_updates import ( run_test_effective_balance_hysteresis, ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_effective_balance_hysteresis_with_compounding_credentials(spec, state): run_test_effective_balance_hysteresis( diff --git a/tests/core/pyspec/eth2spec/test/eip7251/epoch_processing/test_process_pending_balance_deposits.py b/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_pending_balance_deposits.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/eip7251/epoch_processing/test_process_pending_balance_deposits.py rename to tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_pending_balance_deposits.py diff --git a/tests/core/pyspec/eth2spec/test/eip7251/epoch_processing/test_process_pending_consolidations.py b/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_pending_consolidations.py similarity index 99% rename from tests/core/pyspec/eth2spec/test/eip7251/epoch_processing/test_process_pending_consolidations.py rename to tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_pending_consolidations.py index 4f588746e..6c21a722f 100644 --- a/tests/core/pyspec/eth2spec/test/eip7251/epoch_processing/test_process_pending_consolidations.py +++ b/tests/core/pyspec/eth2spec/test/electra/epoch_processing/test_process_pending_consolidations.py @@ -39,7 +39,7 @@ def test_basic_pending_consolidation(spec, state): assert state.pending_consolidations == [] -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_consolidation_not_yet_withdrawable_validator(spec, state): current_epoch = spec.get_current_epoch(state) @@ -128,7 +128,7 @@ def test_skip_consolidation_when_source_slashed(spec, state): ) -@with_eip7251_and_later +@with_electra_and_later @spec_state_test def test_all_consolidation_cases_together(spec, state): current_epoch = spec.get_current_epoch(state) diff --git a/tests/core/pyspec/eth2spec/test/eip7251/__init__.py b/tests/core/pyspec/eth2spec/test/electra/unittests/__init__.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/eip7251/__init__.py rename to tests/core/pyspec/eth2spec/test/electra/unittests/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/eip7251/unittests/test_config_invariants.py b/tests/core/pyspec/eth2spec/test/electra/unittests/test_config_invariants.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/eip7251/unittests/test_config_invariants.py rename to tests/core/pyspec/eth2spec/test/electra/unittests/test_config_invariants.py diff --git a/tests/core/pyspec/eth2spec/test/helpers/deposits.py b/tests/core/pyspec/eth2spec/test/helpers/deposits.py index 1d6a1916f..464563115 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/deposits.py +++ b/tests/core/pyspec/eth2spec/test/helpers/deposits.py @@ -1,7 +1,7 @@ from random import Random from eth2spec.test.context import expect_assertion_error -from eth2spec.test.helpers.forks import is_post_altair, is_post_eip7251 +from eth2spec.test.helpers.forks import is_post_altair, is_post_electra from eth2spec.test.helpers.keys import pubkeys, privkeys from eth2spec.test.helpers.state import get_balance from eth2spec.utils import bls @@ -242,7 +242,7 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef pre_balance = get_balance(state, validator_index) pre_effective_balance = state.validators[validator_index].effective_balance - if is_post_eip7251(spec): + if is_post_electra(spec): pre_pending_deposits = len(state.pending_balance_deposits) yield 'pre', state @@ -271,7 +271,7 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef # new validator is added assert len(state.validators) == pre_validator_count + 1 assert len(state.balances) == pre_validator_count + 1 - if not is_post_eip7251(spec): + if not is_post_electra(spec): if is_top_up: # Top-ups do not change effective balance assert state.validators[validator_index].effective_balance == pre_effective_balance @@ -281,7 +281,7 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef assert state.validators[validator_index].effective_balance == effective_balance assert get_balance(state, validator_index) == pre_balance + deposit.data.amount else: - # no balance or effective balance changes on deposit processing post eip7251 + # no balance or effective balance changes on deposit processing post electra assert get_balance(state, validator_index) == pre_balance assert state.validators[validator_index].effective_balance == pre_effective_balance # new correct balance deposit queued up diff --git a/tests/core/pyspec/eth2spec/test/helpers/execution_layer_exits.py b/tests/core/pyspec/eth2spec/test/helpers/execution_layer_withdrawal_request.py similarity index 58% rename from tests/core/pyspec/eth2spec/test/helpers/execution_layer_exits.py rename to tests/core/pyspec/eth2spec/test/helpers/execution_layer_withdrawal_request.py index e0dda75d1..f111f8943 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/execution_layer_exits.py +++ b/tests/core/pyspec/eth2spec/test/helpers/execution_layer_withdrawal_request.py @@ -7,28 +7,28 @@ from eth2spec.test.helpers.state import get_validator_index_by_pubkey # -def run_execution_layer_exit_processing(spec, state, execution_layer_exit, valid=True, success=True): +def run_execution_layer_withdrawal_request_processing(spec, state, withdrawal_request, valid=True, success=True): """ - Run ``process_execution_layer_exit``, yielding: + Run ``process_execution_layer_withdrawal_request``, yielding: - pre-state ('pre') - - execution_layer_exit ('execution_layer_exit') + - withdrawal_request ('withdrawal_request') - post-state ('post'). If ``valid == False``, run expecting ``AssertionError`` If ``success == False``, it doesn't initiate exit successfully """ - validator_index = get_validator_index_by_pubkey(state, execution_layer_exit.validator_pubkey) + validator_index = get_validator_index_by_pubkey(state, withdrawal_request.validator_pubkey) yield 'pre', state - yield 'execution_layer_exit', execution_layer_exit + yield 'withdrawal_request', withdrawal_request if not valid: - expect_assertion_error(lambda: spec.process_execution_layer_exit(state, execution_layer_exit)) + expect_assertion_error(lambda: spec.process_withdrawal_request(state, withdrawal_request)) yield 'post', None return pre_exit_epoch = state.validators[validator_index].exit_epoch - spec.process_execution_layer_exit(state, execution_layer_exit) + spec.process_withdrawal_request(state, withdrawal_request) yield 'post', state diff --git a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py index 91a2f8fe0..ef6e2f644 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py @@ -36,7 +36,7 @@ def get_execution_payload_header(spec, execution_payload): payload_header.excess_blob_gas = execution_payload.excess_blob_gas if is_post_electra(spec): payload_header.deposit_receipts_root = spec.hash_tree_root(execution_payload.deposit_receipts) - payload_header.exits_root = spec.hash_tree_root(execution_payload.exits) + payload_header.withdrawal_requests_root = spec.hash_tree_root(execution_payload.withdrawal_requests) return payload_header @@ -59,7 +59,7 @@ def compute_el_header_block_hash(spec, transactions_trie_root, withdrawals_trie_root=None, deposit_receipts_trie_root=None, - exits_trie_root=None): + withdrawal_requests_root=None): """ Computes the RLP execution block hash described by an `ExecutionPayloadHeader`. """ @@ -108,8 +108,8 @@ def compute_el_header_block_hash(spec, # deposit_receipts_root assert deposit_receipts_trie_root is not None execution_payload_header_rlp.append((Binary(32, 32), deposit_receipts_trie_root)) - # exits_trie_root - execution_payload_header_rlp.append((Binary(32, 32), exits_trie_root)) + # withdrawal requests root + execution_payload_header_rlp.append((Binary(32, 32), withdrawal_requests_root)) sedes = List([schema for schema, _ in execution_payload_header_rlp]) values = [value for _, value in execution_payload_header_rlp] @@ -137,16 +137,16 @@ def get_withdrawal_rlp(withdrawal): # https://eips.ethereum.org/EIPS/eip-7002 -def get_exit_rlp(exit): - exit_rlp = [ +def get_withdrawal_request_rlp(withdrawal_request): + withdrawal_request_rlp = [ # source_address - (Binary(20, 20), exit.source_address), + (Binary(20, 20), withdrawal_request.source_address), # validator_pubkey - (Binary(48, 48), exit.validator_pubkey), + (Binary(48, 48), withdrawal_request.validator_pubkey), ] - sedes = List([schema for schema, _ in exit_rlp]) - values = [value for _, value in exit_rlp] + sedes = List([schema for schema, _ in withdrawal_request_rlp]) + values = [value for _, value in withdrawal_request_rlp] return encode(values, sedes) @@ -174,7 +174,7 @@ def compute_el_block_hash(spec, payload): withdrawals_trie_root = None deposit_receipts_trie_root = None - exits_trie_root = None + withdrawal_requests_root = None if is_post_capella(spec): withdrawals_encoded = [get_withdrawal_rlp(withdrawal) for withdrawal in payload.withdrawals] @@ -182,8 +182,8 @@ def compute_el_block_hash(spec, payload): if is_post_electra(spec): deposit_receipts_encoded = [get_deposit_receipt_rlp(spec, receipt) for receipt in payload.deposit_receipts] deposit_receipts_trie_root = compute_trie_root_from_indexed_data(deposit_receipts_encoded) - exits_encoded = [get_exit_rlp(exit) for exit in payload.exits] - exits_trie_root = compute_trie_root_from_indexed_data(exits_encoded) + withdrawal_requests_encoded = [get_withdrawal_request_rlp(request) for request in payload.withdrawal_requests] + withdrawal_requests_root = compute_trie_root_from_indexed_data(withdrawal_requests_encoded) payload_header = get_execution_payload_header(spec, payload) @@ -193,7 +193,7 @@ def compute_el_block_hash(spec, payload): transactions_trie_root, withdrawals_trie_root, deposit_receipts_trie_root, - exits_trie_root, + withdrawal_requests_root, ) diff --git a/tests/core/pyspec/eth2spec/test/helpers/proposer_slashings.py b/tests/core/pyspec/eth2spec/test/helpers/proposer_slashings.py index 5d9a36c9b..40f52b139 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/proposer_slashings.py +++ b/tests/core/pyspec/eth2spec/test/helpers/proposer_slashings.py @@ -1,5 +1,5 @@ from eth2spec.test.helpers.block_header import sign_block_header -from eth2spec.test.helpers.forks import is_post_altair, is_post_bellatrix, is_post_eip7251 +from eth2spec.test.helpers.forks import is_post_altair, is_post_bellatrix, is_post_electra from eth2spec.test.helpers.keys import pubkey_to_privkey from eth2spec.test.helpers.state import get_balance from eth2spec.test.helpers.sync_committee import ( @@ -9,8 +9,8 @@ from eth2spec.test.helpers.sync_committee import ( def get_min_slashing_penalty_quotient(spec): - if is_post_eip7251(spec): - return spec.MIN_SLASHING_PENALTY_QUOTIENT_EIP7251 + if is_post_electra(spec): + return spec.MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA elif is_post_bellatrix(spec): return spec.MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX elif is_post_altair(spec): @@ -20,8 +20,8 @@ def get_min_slashing_penalty_quotient(spec): def get_whistleblower_reward_quotient(spec): - if is_post_eip7251(spec): - return spec.WHISTLEBLOWER_REWARD_QUOTIENT_EIP7251 + if is_post_electra(spec): + return spec.WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA else: return spec.WHISTLEBLOWER_REWARD_QUOTIENT diff --git a/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py b/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py index e3dade555..170d33502 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py +++ b/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py @@ -1,9 +1,9 @@ import random -from eth2spec.test.helpers.forks import is_post_eip7251 +from eth2spec.test.helpers.forks import is_post_electra def get_expected_withdrawals(spec, state): - if is_post_eip7251(spec): + if is_post_electra(spec): withdrawals, _ = spec.get_expected_withdrawals(state) return withdrawals else: diff --git a/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py index 6952fca2e..a688952b4 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py +++ b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py @@ -7,7 +7,7 @@ from eth2spec.test.helpers.deposits import ( sign_deposit_data, ) from eth2spec.test.helpers.keys import privkeys, pubkeys -from eth2spec.test.helpers.forks import is_post_eip7251 +from eth2spec.test.helpers.forks import is_post_electra @with_all_phases @@ -124,7 +124,7 @@ def test_top_up__max_effective_balance(spec, state): yield from run_deposit_processing(spec, state, deposit, validator_index) - if not is_post_eip7251(spec): + if not is_post_electra(spec): assert state.balances[validator_index] == spec.MAX_EFFECTIVE_BALANCE + amount assert state.validators[validator_index].effective_balance == spec.MAX_EFFECTIVE_BALANCE @@ -143,7 +143,7 @@ def test_top_up__less_effective_balance(spec, state): yield from run_deposit_processing(spec, state, deposit, validator_index) - if not is_post_eip7251(spec): + if not is_post_electra(spec): assert state.balances[validator_index] == initial_balance + amount # unchanged effective balance assert state.validators[validator_index].effective_balance == initial_effective_balance @@ -163,7 +163,7 @@ def test_top_up__zero_balance(spec, state): yield from run_deposit_processing(spec, state, deposit, validator_index) - if not is_post_eip7251(spec): + if not is_post_electra(spec): assert state.balances[validator_index] == initial_balance + amount # unchanged effective balance assert state.validators[validator_index].effective_balance == initial_effective_balance diff --git a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_effective_balance_updates.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_effective_balance_updates.py index 33c7eb79b..b13bf9cd4 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_effective_balance_updates.py +++ b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_effective_balance_updates.py @@ -3,7 +3,7 @@ from eth2spec.test.helpers.epoch_processing import run_epoch_processing_to from eth2spec.test.helpers.withdrawals import ( set_compounding_withdrawal_credential, ) -from eth2spec.test.helpers.forks import is_post_eip7251 +from eth2spec.test.helpers.forks import is_post_electra @with_all_phases @@ -13,12 +13,12 @@ def test_effective_balance_hysteresis(spec, state): def run_test_effective_balance_hysteresis(spec, state, with_compounding_credentials=False): - assert is_post_eip7251(spec) or not with_compounding_credentials + assert is_post_electra(spec) or not with_compounding_credentials # Prepare state up to the final-updates. # Then overwrite the balances, we only want to focus to be on the hysteresis based changes. run_epoch_processing_to(spec, state, 'process_effective_balance_updates') # Set some edge cases for balances - max = spec.MAX_EFFECTIVE_BALANCE_EIP_7251 if with_compounding_credentials else spec.MIN_ACTIVATION_BALANCE + max = spec.MAX_EFFECTIVE_BALANCE_ELECTRA if with_compounding_credentials else spec.MIN_ACTIVATION_BALANCE min = spec.config.EJECTION_BALANCE inc = spec.EFFECTIVE_BALANCE_INCREMENT div = spec.HYSTERESIS_QUOTIENT diff --git a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py index fff514ce0..7d7d79a17 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py +++ b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py @@ -1,6 +1,6 @@ from eth2spec.test.helpers.deposits import mock_deposit from eth2spec.test.helpers.state import next_epoch, next_slots -from eth2spec.test.helpers.forks import is_post_eip7251 +from eth2spec.test.helpers.forks import is_post_electra from eth2spec.test.helpers.constants import MINIMAL from eth2spec.test.context import ( spec_test, spec_state_test, @@ -106,7 +106,7 @@ def test_activation_queue_sorting(spec, state): yield from run_process_registry_updates(spec, state) - if is_post_eip7251(spec): + if is_post_electra(spec): # NOTE: EIP-7521 changed how activations are gated # given the prefix setup here, all validators should be activated activation_epochs = [state.validators[i].activation_epoch for i in range(mock_activations)] @@ -150,7 +150,7 @@ def run_test_activation_queue_efficiency(spec, state): for i in range(mock_activations): # NOTE: EIP-7251 changes how activations are gated # given the prefix setup here, all validators are eligible for activation - if i < churn_limit_0 or is_post_eip7251(spec): + if i < churn_limit_0 or is_post_electra(spec): assert state.validators[i].activation_epoch < spec.FAR_FUTURE_EPOCH else: assert state.validators[i].activation_epoch == spec.FAR_FUTURE_EPOCH @@ -214,7 +214,7 @@ def run_test_ejection_past_churn_limit(spec, state): yield from run_process_registry_updates(spec, state) - if is_post_eip7251(spec): + if is_post_electra(spec): per_epoch_churn = spec.get_activation_exit_churn_limit(state) def map_index_to_exit_epoch(i): @@ -311,7 +311,7 @@ def run_test_activation_queue_activation_and_ejection(spec, state, num_per_statu assert validator.activation_eligibility_epoch != spec.FAR_FUTURE_EPOCH # NOTE: activations are gated differently after EIP-7251 # all eligible validators were activated, regardless of churn limit - if not is_post_eip7251(spec): + if not is_post_electra(spec): assert validator.activation_epoch == spec.FAR_FUTURE_EPOCH # all ejection balance validators ejected for a future epoch @@ -394,7 +394,7 @@ def test_invalid_large_withdrawable_epoch(spec, state): state.validators[0].exit_epoch = exit_epoch state.validators[1].effective_balance = spec.config.EJECTION_BALANCE - if is_post_eip7251(spec): + if is_post_electra(spec): state.earliest_exit_epoch = exit_epoch try: diff --git a/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py index 7c4140eb3..41ba2e8b7 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py @@ -34,7 +34,7 @@ from eth2spec.test.helpers.constants import PHASE0, MINIMAL from eth2spec.test.helpers.forks import ( is_post_altair, is_post_bellatrix, - is_post_eip7251, + is_post_electra, is_post_capella, ) from eth2spec.test.context import ( @@ -744,7 +744,7 @@ def test_deposit_in_block(spec, state): yield 'blocks', [signed_block] yield 'post', state - if is_post_eip7251(spec): + if is_post_electra(spec): balance = state.pending_balance_deposits[0].amount else: balance = get_balance(state, validator_index) @@ -815,7 +815,7 @@ def test_deposit_top_up(spec, state): ) balance = get_balance(state, validator_index) - if is_post_eip7251(spec): + if is_post_electra(spec): balance += state.pending_balance_deposits[0].amount assert balance == (