Merge pull request #3052 from Inphi/inphi/eip4844-rebase

Rebase EIP-4844 on Capella
This commit is contained in:
Hsiao-Wei Wang
2022-11-18 03:16:58 +08:00
committed by GitHub
15 changed files with 223 additions and 92 deletions

View File

@@ -618,14 +618,14 @@ from eth2spec.bellatrix import {preset_name} as bellatrix
#
# EIP4844SpecBuilder
#
class EIP4844SpecBuilder(BellatrixSpecBuilder):
class EIP4844SpecBuilder(CapellaSpecBuilder):
fork: str = EIP4844
@classmethod
def imports(cls, preset_name: str):
return super().imports(preset_name) + f'''
from eth2spec.utils import kzg
from eth2spec.bellatrix import {preset_name} as bellatrix
from eth2spec.capella import {preset_name} as capella
'''
@@ -652,6 +652,32 @@ KZG_SETUP_LAGRANGE = TESTING_KZG_SETUP_LAGRANGE
ROOTS_OF_UNITY = kzg.compute_roots_of_unity(TESTING_FIELD_ELEMENTS_PER_BLOB)
#
# Temporarily disable Withdrawals functions for EIP4844 testnets
#
def no_op(fn): # type: ignore
def wrapper(*args, **kw): # type: ignore
return None
return wrapper
def get_empty_list_result(fn): # type: ignore
def wrapper(*args, **kw): # type: ignore
return []
return wrapper
process_withdrawals = no_op(process_withdrawals)
process_bls_to_execution_change = no_op(process_bls_to_execution_change)
get_expected_withdrawals = get_empty_list_result(get_expected_withdrawals)
#
# End
#
def retrieve_blobs_sidecar(slot: Slot, beacon_block_root: Root) -> Optional[BlobsSidecar]:
return "TEST"'''
@@ -1002,7 +1028,7 @@ class PySpecCommand(Command):
specs/bellatrix/p2p-interface.md
sync/optimistic.md
"""
if self.spec_fork == CAPELLA:
if self.spec_fork in (CAPELLA, EIP4844):
self.md_doc_paths += """
specs/capella/beacon-chain.md
specs/capella/fork.md

View File

@@ -33,13 +33,14 @@
- [`process_execution_payload`](#process_execution_payload)
- [Blob KZG commitments](#blob-kzg-commitments)
- [Testing](#testing)
- [Disabling Withdrawals](#disabling-withdrawals)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
## Introduction
This upgrade adds blobs to the beacon chain as part of EIP-4844.
This upgrade adds blobs to the beacon chain as part of EIP-4844. This is an extension of the Capella upgrade.
## Custom types
@@ -89,6 +90,7 @@ class BeaconBlockBody(Container):
sync_aggregate: SyncAggregate
# Execution
execution_payload: ExecutionPayload
bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES]
blob_kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK] # [New in EIP-4844]
```
@@ -109,10 +111,11 @@ class ExecutionPayload(Container):
timestamp: uint64
extra_data: ByteList[MAX_EXTRA_DATA_BYTES]
base_fee_per_gas: uint256
excess_blobs: uint64 # [New in EIP-4844]
excess_data_gas: uint256 # [New in EIP-4844]
# Extra payload fields
block_hash: Hash32 # Hash of execution block
transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]
withdrawals: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]
```
#### `ExecutionPayloadHeader`
@@ -132,10 +135,11 @@ class ExecutionPayloadHeader(Container):
timestamp: uint64
extra_data: ByteList[MAX_EXTRA_DATA_BYTES]
base_fee_per_gas: uint256
excess_blobs: uint64 # [New in EIP-4844]
excess_data_gas: uint256 # [New in EIP-4844]
# Extra payload fields
block_hash: Hash32 # Hash of execution block
transactions_root: Root
withdrawals_root: Root
```
## Helper functions
@@ -227,7 +231,8 @@ def verify_kzg_commitments_against_transactions(transactions: Sequence[Transacti
def process_block(state: BeaconState, block: BeaconBlock) -> None:
process_block_header(state, block)
if is_execution_enabled(state, block.body):
process_execution_payload(state, block.body.execution_payload, EXECUTION_ENGINE)
process_withdrawals(state, block.body.execution_payload)
process_execution_payload(state, block.body.execution_payload, EXECUTION_ENGINE) # [Modified in EIP-4844]
process_randao(state, block.body)
process_eth1_data(state, block.body)
process_operations(state, block.body)
@@ -253,6 +258,7 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe
assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)
# Verify the execution payload is valid
assert execution_engine.notify_new_payload(payload)
# Cache execution payload header
state.latest_execution_payload_header = ExecutionPayloadHeader(
parent_hash=payload.parent_hash,
@@ -267,9 +273,10 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe
timestamp=payload.timestamp,
extra_data=payload.extra_data,
base_fee_per_gas=payload.base_fee_per_gas,
excess_blobs=payload.excess_blobs, # [New in EIP-4844]
excess_data_gas=payload.excess_data_gas, # [New in EIP-4844]
block_hash=payload.block_hash,
transactions_root=hash_tree_root(payload.transactions),
withdrawals_root=hash_tree_root(payload.withdrawals),
)
```
@@ -335,3 +342,10 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32,
return state
```
### Disabling Withdrawals
During testing we avoid Capella-specific updates to the state transition. We do this by replacing the following functions with a no-op implementation:
- `process_withdrawals`
- `process_bls_to_execution_change`
The `get_expected_withdrawals` function is also modified to return an empty withdrawals list. As such, the PayloadAttributes used to update forkchoice does not contain withdrawals.

View File

@@ -44,6 +44,8 @@ def compute_fork_version(epoch: Epoch) -> Version:
"""
if epoch >= EIP4844_FORK_EPOCH:
return EIP4844_FORK_VERSION
if epoch >= CAPELLA_FORK_EPOCH:
return CAPELLA_FORK_VERSION
if epoch >= BELLATRIX_FORK_EPOCH:
return BELLATRIX_FORK_VERSION
if epoch >= ALTAIR_FORK_EPOCH:
@@ -62,12 +64,11 @@ Note that for the pure EIP-4844 networks, we don't apply `upgrade_to_eip4844` si
### Upgrading the state
Since the `eip4844.BeaconState` format is equal to the `bellatrix.BeaconState` format, we only have to update `BeaconState.fork`.
Since the `eip4844.BeaconState` format is equal to the `capella.BeaconState` format, we only have to update `BeaconState.fork`.
```python
def upgrade_to_eip4844(pre: bellatrix.BeaconState) -> BeaconState:
# TODO: if Capella gets scheduled, add sync it with Capella.BeaconState
epoch = bellatrix.get_current_epoch(pre)
def upgrade_to_eip4844(pre: capella.BeaconState) -> BeaconState:
epoch = capella.get_current_epoch(pre)
latest_execution_payload_header = ExecutionPayloadHeader(
parent_hash=pre.latest_execution_payload_header.parent_hash,
fee_recipient=pre.latest_execution_payload_header.fee_recipient,
@@ -81,7 +82,7 @@ def upgrade_to_eip4844(pre: bellatrix.BeaconState) -> BeaconState:
timestamp=pre.latest_execution_payload_header.timestamp,
extra_data=pre.latest_execution_payload_header.extra_data,
base_fee_per_gas=pre.latest_execution_payload_header.base_fee_per_gas,
excess_data_gas=uint256(0), # [New in EIP-4844]
excess_data_gas=uint256(0), # [New in EIP-4844]
block_hash=pre.latest_execution_payload_header.block_hash,
transactions_root=pre.latest_execution_payload_header.transactions_root,
withdrawals_root=pre.latest_execution_payload_header.withdrawals_root,
@@ -126,7 +127,10 @@ def upgrade_to_eip4844(pre: bellatrix.BeaconState) -> BeaconState:
current_sync_committee=pre.current_sync_committee,
next_sync_committee=pre.next_sync_committee,
# Execution-layer
latest_execution_payload_header=latest_execution_payload_header,
latest_execution_payload_header=latest_execution_payload_header, # [Modified in EIP4844]
# Withdrawals
next_withdrawal_index=pre.next_withdrawal_index,
next_withdrawal_validator_index=pre.next_withdrawal_validator_index,
)
return post

View File

@@ -133,6 +133,7 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
| `EIP4844_FORK_VERSION` | `eip4844.SignedBeaconBlock` |
#### BeaconBlocksByRoot v2
@@ -151,6 +152,7 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
#### BeaconBlockAndBlobsSidecarByRoot v1

View File

@@ -29,7 +29,7 @@ This document represents the changes to be made in the code of an "honest valida
## Prerequisites
This document is an extension of the [Bellatrix -- Honest Validator](../bellatrix/validator.md) guide.
This document is an extension of the [Capella -- Honest Validator](../capella/validator.md) guide.
All behaviors and definitions defined in this document, and documents it extends, carry over unless explicitly noted or overridden.
All terminology, constants, functions, and protocol mechanics defined in the updated [Beacon Chain doc of EIP4844](./beacon-chain.md) are requisite for this document and used throughout.
@@ -60,7 +60,7 @@ Namely, the blob handling and the addition of `SignedBeaconBlockAndBlobsSidecar`
##### Blob KZG commitments
1. After retrieving the execution payload from the execution engine as specified in Bellatrix,
1. After retrieving the execution payload from the execution engine as specified in Capella,
use the `payload_id` to retrieve `blobs` and `blob_kzg_commitments` via `get_blobs_and_kzg_commitments(payload_id)`.
2. Validate `blobs` and `blob_kzg_commitments`:

View File

@@ -1,7 +1,8 @@
from eth2spec.test.helpers.constants import CAPELLA
from eth2spec.test.helpers.keys import pubkeys
from eth2spec.test.helpers.bls_to_execution_changes import get_signed_address_change
from eth2spec.test.context import spec_state_test, expect_assertion_error, with_capella_and_later, always_bls
from eth2spec.test.context import spec_state_test, expect_assertion_error, with_phases, always_bls
def run_bls_to_execution_change_processing(spec, state, signed_address_change, valid=True):
@@ -37,14 +38,14 @@ def run_bls_to_execution_change_processing(spec, state, signed_address_change, v
yield 'post', state
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success(spec, state):
signed_address_change = get_signed_address_change(spec, state)
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_not_activated(spec, state):
validator_index = 3
@@ -62,7 +63,7 @@ def test_success_not_activated(spec, state):
assert not spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_in_activation_queue(spec, state):
validator_index = 3
@@ -80,7 +81,7 @@ def test_success_in_activation_queue(spec, state):
assert not spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_in_exit_queue(spec, state):
validator_index = 3
@@ -93,7 +94,7 @@ def test_success_in_exit_queue(spec, state):
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_exited(spec, state):
validator_index = 4
@@ -110,7 +111,7 @@ def test_success_exited(spec, state):
assert not spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_withdrawable(spec, state):
validator_index = 4
@@ -128,7 +129,7 @@ def test_success_withdrawable(spec, state):
assert spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_val_index_out_of_range(spec, state):
# Create for one validator beyond the validator list length
@@ -137,7 +138,7 @@ def test_fail_val_index_out_of_range(spec, state):
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_already_0x01(spec, state):
# Create for one validator beyond the validator list length
@@ -149,7 +150,7 @@ def test_fail_already_0x01(spec, state):
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_incorrect_from_bls_pubkey(spec, state):
# Create for one validator beyond the validator list length
@@ -163,7 +164,7 @@ def test_fail_incorrect_from_bls_pubkey(spec, state):
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
@always_bls
def test_fail_bad_signature(spec, state):

View File

@@ -1,7 +1,8 @@
from eth2spec.test.context import (
spec_state_test,
with_capella_and_later,
with_phases,
)
from eth2spec.test.helpers.constants import CAPELLA
from eth2spec.test.helpers.state import next_epoch_via_block
from eth2spec.test.helpers.deposits import (
prepare_state_and_deposit,
@@ -10,7 +11,7 @@ from eth2spec.test.helpers.deposits import (
from eth2spec.test.helpers.withdrawals import set_validator_fully_withdrawable
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_top_up_to_withdrawn_validator(spec, state):
validator_index = 0

View File

@@ -3,10 +3,10 @@ import random
from eth2spec.test.context import (
spec_state_test,
expect_assertion_error,
with_capella_and_later,
with_presets,
with_phases,
)
from eth2spec.test.helpers.constants import MINIMAL
from eth2spec.test.helpers.constants import MINIMAL, CAPELLA
from eth2spec.test.helpers.execution_payload import (
build_empty_execution_payload,
)
@@ -87,7 +87,7 @@ def run_withdrawals_processing(spec, state, execution_payload, num_expected_with
return expected_withdrawals
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_zero_expected_withdrawals(spec, state):
assert len(spec.get_expected_withdrawals(state)) == 0
@@ -98,7 +98,7 @@ def test_success_zero_expected_withdrawals(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_one_full_withdrawal(spec, state):
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
@@ -115,7 +115,7 @@ def test_success_one_full_withdrawal(spec, state):
partial_withdrawals_indices=partial_withdrawals_indices)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_one_partial_withdrawal(spec, state):
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
@@ -135,7 +135,7 @@ def test_success_one_partial_withdrawal(spec, state):
)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_max_per_slot(spec, state):
num_full_withdrawals = spec.MAX_WITHDRAWALS_PER_PAYLOAD // 2
@@ -153,7 +153,7 @@ def test_success_max_per_slot(spec, state):
partial_withdrawals_indices=partial_withdrawals_indices)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_all_fully_withdrawable(spec, state):
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
@@ -168,7 +168,7 @@ def test_success_all_fully_withdrawable(spec, state):
partial_withdrawals_indices=partial_withdrawals_indices)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_all_partially_withdrawable(spec, state):
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
@@ -187,7 +187,7 @@ def test_success_all_partially_withdrawable(spec, state):
# Failure cases in which the number of withdrawals in the execution_payload is incorrect
#
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_non_withdrawable_non_empty_withdrawals(spec, state):
next_slot(spec, state)
@@ -203,7 +203,7 @@ def test_fail_non_withdrawable_non_empty_withdrawals(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_one_expected_full_withdrawal_and_none_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
@@ -215,7 +215,7 @@ def test_fail_one_expected_full_withdrawal_and_none_in_withdrawals(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_one_expected_partial_withdrawal_and_none_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=1)
@@ -227,7 +227,7 @@ def test_fail_one_expected_partial_withdrawal_and_none_in_withdrawals(spec, stat
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_one_expected_full_withdrawal_and_duplicate_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=2)
@@ -239,7 +239,7 @@ def test_fail_one_expected_full_withdrawal_and_duplicate_in_withdrawals(spec, st
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_two_expected_partial_withdrawal_and_duplicate_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=2)
@@ -251,7 +251,7 @@ def test_fail_two_expected_partial_withdrawal_and_duplicate_in_withdrawals(spec,
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_max_per_slot_full_withdrawals_and_one_less_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD)
@@ -263,7 +263,7 @@ def test_fail_max_per_slot_full_withdrawals_and_one_less_in_withdrawals(spec, st
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_max_per_slot_partial_withdrawals_and_one_less_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD)
@@ -275,7 +275,7 @@ def test_fail_max_per_slot_partial_withdrawals_and_one_less_in_withdrawals(spec,
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_a_lot_fully_withdrawable_too_few_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
@@ -287,7 +287,7 @@ def test_fail_a_lot_fully_withdrawable_too_few_in_withdrawals(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_a_lot_partially_withdrawable_too_few_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
@@ -299,7 +299,7 @@ def test_fail_a_lot_partially_withdrawable_too_few_in_withdrawals(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_a_lot_mixed_withdrawable_in_queue_too_few_in_withdrawals(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4,
@@ -316,7 +316,7 @@ def test_fail_a_lot_mixed_withdrawable_in_queue_too_few_in_withdrawals(spec, sta
# Failure cases in which the withdrawals in the execution_payload are incorrect
#
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_incorrect_withdrawal_index(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
@@ -328,7 +328,7 @@ def test_fail_incorrect_withdrawal_index(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_incorrect_address_full(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
@@ -340,7 +340,7 @@ def test_fail_incorrect_address_full(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_incorrect_address_partial(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=1)
@@ -352,7 +352,7 @@ def test_fail_incorrect_address_partial(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_incorrect_amount_full(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
@@ -364,7 +364,7 @@ def test_fail_incorrect_amount_full(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_incorrect_amount_partial(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
@@ -376,7 +376,7 @@ def test_fail_incorrect_amount_partial(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_one_of_many_incorrectly_full(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
@@ -394,7 +394,7 @@ def test_fail_one_of_many_incorrectly_full(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_one_of_many_incorrectly_partial(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
@@ -412,7 +412,7 @@ def test_fail_one_of_many_incorrectly_partial(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_many_incorrectly_full(spec, state):
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
@@ -430,7 +430,7 @@ def test_fail_many_incorrectly_full(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_many_incorrectly_partial(spec, state):
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
@@ -452,7 +452,7 @@ def test_fail_many_incorrectly_partial(spec, state):
# More full withdrawal cases
#
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_withdrawable_epoch_but_0_balance(spec, state):
current_epoch = spec.get_current_epoch(state)
@@ -466,7 +466,7 @@ def test_withdrawable_epoch_but_0_balance(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_withdrawable_epoch_but_0_effective_balance_0_balance(spec, state):
current_epoch = spec.get_current_epoch(state)
@@ -480,7 +480,7 @@ def test_withdrawable_epoch_but_0_effective_balance_0_balance(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_withdrawable_epoch_but_0_effective_balance_nonzero_balance(spec, state):
current_epoch = spec.get_current_epoch(state)
@@ -494,7 +494,7 @@ def test_withdrawable_epoch_but_0_effective_balance_nonzero_balance(spec, state)
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_no_withdrawals_but_some_next_epoch(spec, state):
current_epoch = spec.get_current_epoch(state)
@@ -508,7 +508,7 @@ def test_no_withdrawals_but_some_next_epoch(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_all_withdrawal(spec, state):
# Make all validators withdrawable
@@ -544,25 +544,25 @@ def run_random_full_withdrawals_test(spec, state, rng):
yield from run_withdrawals_processing(spec, state, execution_payload)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_random_full_withdrawals_0(spec, state):
yield from run_random_full_withdrawals_test(spec, state, random.Random(444))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_random_full_withdrawals_1(spec, state):
yield from run_random_full_withdrawals_test(spec, state, random.Random(420))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_random_full_withdrawals_2(spec, state):
yield from run_random_full_withdrawals_test(spec, state, random.Random(200))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_random_full_withdrawals_3(spec, state):
yield from run_random_full_withdrawals_test(spec, state, random.Random(2000000))
@@ -572,7 +572,7 @@ def test_random_full_withdrawals_3(spec, state):
# More partial withdrawal cases
#
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_no_max_effective_balance(spec, state):
validator_index = len(state.validators) // 2
@@ -588,7 +588,7 @@ def test_success_no_max_effective_balance(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_no_excess_balance(spec, state):
validator_index = len(state.validators) // 2
@@ -604,7 +604,7 @@ def test_success_no_excess_balance(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_excess_balance_but_no_max_effective_balance(spec, state):
validator_index = len(state.validators) // 2
@@ -621,7 +621,7 @@ def test_success_excess_balance_but_no_max_effective_balance(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_one_partial_withdrawable_not_yet_active(spec, state):
validator_index = len(state.validators) // 2
@@ -635,7 +635,7 @@ def test_success_one_partial_withdrawable_not_yet_active(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_one_partial_withdrawable_in_exit_queue(spec, state):
validator_index = len(state.validators) // 2
@@ -650,7 +650,7 @@ def test_success_one_partial_withdrawable_in_exit_queue(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_one_partial_withdrawable_exited(spec, state):
validator_index = len(state.validators) // 2
@@ -664,7 +664,7 @@ def test_success_one_partial_withdrawable_exited(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_one_partial_withdrawable_active_and_slashed(spec, state):
validator_index = len(state.validators) // 2
@@ -678,7 +678,7 @@ def test_success_one_partial_withdrawable_active_and_slashed(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_one_partial_withdrawable_exited_and_slashed(spec, state):
validator_index = len(state.validators) // 2
@@ -693,7 +693,7 @@ def test_success_one_partial_withdrawable_exited_and_slashed(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_two_partial_withdrawable(spec, state):
set_validator_partially_withdrawable(spec, state, 0)
@@ -704,7 +704,7 @@ def test_success_two_partial_withdrawable(spec, state):
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=2)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_max_partial_withdrawable(spec, state):
# Sanity check that this test works for this state
@@ -719,7 +719,7 @@ def test_success_max_partial_withdrawable(spec, state):
spec, state, execution_payload, num_expected_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD)
@with_capella_and_later
@with_phases([CAPELLA])
@with_presets([MINIMAL], reason="not enough validators with mainnet config")
@spec_state_test
def test_success_max_plus_one_withdrawable(spec, state):
@@ -758,37 +758,37 @@ def run_random_partial_withdrawals_test(spec, state, rng):
yield from run_withdrawals_processing(spec, state, execution_payload)
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_random_0(spec, state):
yield from run_random_partial_withdrawals_test(spec, state, random.Random(0))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_random_partial_withdrawals_1(spec, state):
yield from run_random_partial_withdrawals_test(spec, state, random.Random(1))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_random_partial_withdrawals_2(spec, state):
yield from run_random_partial_withdrawals_test(spec, state, random.Random(2))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_random_partial_withdrawals_3(spec, state):
yield from run_random_partial_withdrawals_test(spec, state, random.Random(3))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_random_partial_withdrawals_4(spec, state):
yield from run_random_partial_withdrawals_test(spec, state, random.Random(4))
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_random_partial_withdrawals_5(spec, state):
yield from run_random_partial_withdrawals_test(spec, state, random.Random(5))

View File

@@ -1,7 +1,7 @@
from eth2spec.test.context import (
with_capella_and_later, spec_state_test
with_phases, spec_state_test
)
from eth2spec.test.helpers.constants import CAPELLA
from eth2spec.test.helpers.state import (
state_transition_and_sign_block,
)
@@ -21,7 +21,7 @@ from eth2spec.test.helpers.withdrawals import (
from eth2spec.test.helpers.voluntary_exits import prepare_signed_exits
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_successful_bls_change(spec, state):
index = 0
@@ -44,7 +44,7 @@ def test_successful_bls_change(spec, state):
assert post_credentials[12:] == signed_address_change.message.to_execution_address
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_full_withdrawal_in_epoch_transition(spec, state):
index = 0
@@ -65,7 +65,7 @@ def test_full_withdrawal_in_epoch_transition(spec, state):
assert len(spec.get_expected_withdrawals(state)) == 0
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_partial_withdrawal_in_epoch_transition(spec, state):
index = state.next_withdrawal_index
@@ -89,7 +89,7 @@ def test_partial_withdrawal_in_epoch_transition(spec, state):
assert len(spec.get_expected_withdrawals(state)) == 0
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_many_partial_withdrawals_in_epoch_transition(spec, state):
assert len(state.validators) > spec.MAX_WITHDRAWALS_PER_PAYLOAD
@@ -112,7 +112,7 @@ def test_many_partial_withdrawals_in_epoch_transition(spec, state):
assert len(spec.get_expected_withdrawals(state)) == 1
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_exit_and_bls_change(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
@@ -170,7 +170,7 @@ def _perform_valid_withdrawal(spec, state):
return pre_state, signed_block_1, pre_next_withdrawal_index
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_withdrawal_success_two_blocks(spec, state):
pre_state, signed_block_1, pre_next_withdrawal_index = _perform_valid_withdrawal(spec, state)
@@ -187,7 +187,7 @@ def test_withdrawal_success_two_blocks(spec, state):
yield 'post', state
@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_withdrawal_fail_second_block_payload_isnt_compatible(spec, state):
_perform_valid_withdrawal(spec, state)

View File

@@ -306,6 +306,7 @@ def config_fork_epoch_overrides(spec, state):
elif _check_current_version(spec, state, EIP4844):
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['BELLATRIX_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['CAPELLA_FORK_EPOCH'] = spec.GENESIS_EPOCH
overrides['EIP4844_FORK_EPOCH'] = spec.GENESIS_EPOCH
elif _check_current_version(spec, state, SHARDING):
overrides['ALTAIR_FORK_EPOCH'] = spec.GENESIS_EPOCH

View File

@@ -0,0 +1,40 @@
from eth2spec.test.helpers.bls_to_execution_changes import get_signed_address_change
from eth2spec.test.context import spec_state_test, expect_assertion_error, with_eip4844_and_later
def run_bls_to_execution_change_processing_no_op(spec, state, signed_address_change, valid=True):
"""
Run ``process_bls_to_execution_change``, yielding:
- pre-state ('pre')
- address-change ('address_change')
- post-state ('post').
If ``valid == False``, run expecting ``AssertionError``
"""
pre_state = state.copy()
# yield pre-state
yield 'pre', state
yield 'address_change', signed_address_change
# If the address_change is invalid, processing is aborted, and there is no post-state.
if not valid:
expect_assertion_error(lambda: spec.process_bls_to_execution_change(state, signed_address_change))
yield 'post', None
return
# process address change
spec.process_bls_to_execution_change(state, signed_address_change)
# yield post-state
yield 'post', state
# Make sure state has NOT been changed
assert state == pre_state
@with_eip4844_and_later
@spec_state_test
def test_no_op(spec, state):
signed_address_change = get_signed_address_change(spec, state)
yield from run_bls_to_execution_change_processing_no_op(spec, state, signed_address_change)

View File

@@ -0,0 +1,41 @@
from eth2spec.test.context import spec_state_test, expect_assertion_error, with_eip4844_and_later
from eth2spec.test.helpers.execution_payload import (
build_empty_execution_payload,
)
from eth2spec.test.helpers.state import next_slot
def run_withdrawals_processing(spec, state, execution_payload, valid=True):
"""
Run ``process_execution_payload``, yielding:
- pre-state ('pre')
- execution payload ('execution_payload')
- post-state ('post').
If ``valid == False``, run expecting ``AssertionError``
"""
pre_state = state.copy()
yield 'pre', state
yield 'execution_payload', execution_payload
if not valid:
expect_assertion_error(lambda: spec.process_withdrawals(state, execution_payload))
yield 'post', None
return
spec.process_withdrawals(state, execution_payload)
yield 'post', state
# Make sure state has NOT been changed
assert state == pre_state
@with_eip4844_and_later
@spec_state_test
def test_no_op(spec, state):
next_slot(spec, state)
execution_payload = build_empty_execution_payload(spec, state)
yield from run_withdrawals_processing(spec, state, execution_payload)

View File

@@ -32,6 +32,7 @@ ALL_FORK_UPGRADES = {
PHASE0: ALTAIR,
ALTAIR: BELLATRIX,
BELLATRIX: CAPELLA,
CAPELLA: EIP4844,
}
ALL_PRE_POST_FORKS = ALL_FORK_UPGRADES.items()
AFTER_BELLATRIX_UPGRADES = {key: value for key, value in ALL_FORK_UPGRADES.items() if key != PHASE0}

View File

@@ -5,7 +5,7 @@ from .constants import (
def is_post_fork(a, b):
if a == EIP4844:
return b in [PHASE0, ALTAIR, BELLATRIX, EIP4844]
return b in [PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844]
if a == CAPELLA:
return b in [PHASE0, ALTAIR, BELLATRIX, CAPELLA]
if a == BELLATRIX: