Merge branch 'dev' into sf-epochoverrides
This commit is contained in:
commit
c3000ed996
41
setup.py
41
setup.py
|
@ -618,14 +618,13 @@ from eth2spec.bellatrix import {preset_name} as bellatrix
|
||||||
#
|
#
|
||||||
# EIP4844SpecBuilder
|
# EIP4844SpecBuilder
|
||||||
#
|
#
|
||||||
class EIP4844SpecBuilder(BellatrixSpecBuilder):
|
class EIP4844SpecBuilder(CapellaSpecBuilder):
|
||||||
fork: str = EIP4844
|
fork: str = EIP4844
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def imports(cls, preset_name: str):
|
def imports(cls, preset_name: str):
|
||||||
return super().imports(preset_name) + f'''
|
return super().imports(preset_name) + f'''
|
||||||
from eth2spec.utils import kzg
|
from eth2spec.capella import {preset_name} as capella
|
||||||
from eth2spec.bellatrix import {preset_name} as bellatrix
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
@ -638,19 +637,31 @@ T = TypeVar('T') # For generic function
|
||||||
@classmethod
|
@classmethod
|
||||||
def sundry_functions(cls) -> str:
|
def sundry_functions(cls) -> str:
|
||||||
return super().sundry_functions() + '\n\n' + '''
|
return super().sundry_functions() + '\n\n' + '''
|
||||||
# TODO: for mainnet, load pre-generated trusted setup file to reduce building time.
|
#
|
||||||
# TESTING_FIELD_ELEMENTS_PER_BLOB is hardcoded copy from minimal presets
|
# Temporarily disable Withdrawals functions for EIP4844 testnets
|
||||||
TESTING_FIELD_ELEMENTS_PER_BLOB = 4
|
#
|
||||||
TESTING_SECRET = 1337
|
|
||||||
TESTING_KZG_SETUP_G1 = kzg.generate_setup(bls.G1, TESTING_SECRET, TESTING_FIELD_ELEMENTS_PER_BLOB)
|
|
||||||
TESTING_KZG_SETUP_G2 = kzg.generate_setup(bls.G2, TESTING_SECRET, TESTING_FIELD_ELEMENTS_PER_BLOB)
|
|
||||||
TESTING_KZG_SETUP_LAGRANGE = kzg.get_lagrange(TESTING_KZG_SETUP_G1)
|
|
||||||
|
|
||||||
KZG_SETUP_G1 = [bls.G1_to_bytes48(p) for p in TESTING_KZG_SETUP_G1]
|
|
||||||
KZG_SETUP_G2 = [bls.G2_to_bytes96(p) for p in TESTING_KZG_SETUP_G2]
|
|
||||||
KZG_SETUP_LAGRANGE = TESTING_KZG_SETUP_LAGRANGE
|
|
||||||
ROOTS_OF_UNITY = kzg.compute_roots_of_unity(TESTING_FIELD_ELEMENTS_PER_BLOB)
|
|
||||||
|
|
||||||
|
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]:
|
def retrieve_blobs_sidecar(slot: Slot, beacon_block_root: Root) -> Optional[BlobsSidecar]:
|
||||||
return "TEST"'''
|
return "TEST"'''
|
||||||
|
@ -1002,7 +1013,7 @@ class PySpecCommand(Command):
|
||||||
specs/bellatrix/p2p-interface.md
|
specs/bellatrix/p2p-interface.md
|
||||||
sync/optimistic.md
|
sync/optimistic.md
|
||||||
"""
|
"""
|
||||||
if self.spec_fork == CAPELLA:
|
if self.spec_fork in (CAPELLA, EIP4844):
|
||||||
self.md_doc_paths += """
|
self.md_doc_paths += """
|
||||||
specs/capella/beacon-chain.md
|
specs/capella/beacon-chain.md
|
||||||
specs/capella/fork.md
|
specs/capella/fork.md
|
||||||
|
|
|
@ -33,13 +33,14 @@
|
||||||
- [`process_execution_payload`](#process_execution_payload)
|
- [`process_execution_payload`](#process_execution_payload)
|
||||||
- [Blob KZG commitments](#blob-kzg-commitments)
|
- [Blob KZG commitments](#blob-kzg-commitments)
|
||||||
- [Testing](#testing)
|
- [Testing](#testing)
|
||||||
|
- [Disabling Withdrawals](#disabling-withdrawals)
|
||||||
|
|
||||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
<!-- /TOC -->
|
<!-- /TOC -->
|
||||||
|
|
||||||
## Introduction
|
## 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
|
## Custom types
|
||||||
|
|
||||||
|
@ -88,7 +89,8 @@ class BeaconBlockBody(Container):
|
||||||
voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS]
|
voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS]
|
||||||
sync_aggregate: SyncAggregate
|
sync_aggregate: SyncAggregate
|
||||||
# Execution
|
# Execution
|
||||||
execution_payload: ExecutionPayload
|
execution_payload: ExecutionPayload # [Modified in EIP-4844]
|
||||||
|
bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES]
|
||||||
blob_kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK] # [New in EIP-4844]
|
blob_kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK] # [New in EIP-4844]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -109,10 +111,11 @@ class ExecutionPayload(Container):
|
||||||
timestamp: uint64
|
timestamp: uint64
|
||||||
extra_data: ByteList[MAX_EXTRA_DATA_BYTES]
|
extra_data: ByteList[MAX_EXTRA_DATA_BYTES]
|
||||||
base_fee_per_gas: uint256
|
base_fee_per_gas: uint256
|
||||||
excess_blobs: uint64 # [New in EIP-4844]
|
excess_data_gas: uint256 # [New in EIP-4844]
|
||||||
# Extra payload fields
|
# Extra payload fields
|
||||||
block_hash: Hash32 # Hash of execution block
|
block_hash: Hash32 # Hash of execution block
|
||||||
transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]
|
transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]
|
||||||
|
withdrawals: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `ExecutionPayloadHeader`
|
#### `ExecutionPayloadHeader`
|
||||||
|
@ -132,10 +135,11 @@ class ExecutionPayloadHeader(Container):
|
||||||
timestamp: uint64
|
timestamp: uint64
|
||||||
extra_data: ByteList[MAX_EXTRA_DATA_BYTES]
|
extra_data: ByteList[MAX_EXTRA_DATA_BYTES]
|
||||||
base_fee_per_gas: uint256
|
base_fee_per_gas: uint256
|
||||||
excess_blobs: uint64 # [New in EIP-4844]
|
excess_data_gas: uint256 # [New in EIP-4844]
|
||||||
# Extra payload fields
|
# Extra payload fields
|
||||||
block_hash: Hash32 # Hash of execution block
|
block_hash: Hash32 # Hash of execution block
|
||||||
transactions_root: Root
|
transactions_root: Root
|
||||||
|
withdrawals_root: Root
|
||||||
```
|
```
|
||||||
|
|
||||||
## Helper functions
|
## Helper functions
|
||||||
|
@ -227,7 +231,8 @@ def verify_kzg_commitments_against_transactions(transactions: Sequence[Transacti
|
||||||
def process_block(state: BeaconState, block: BeaconBlock) -> None:
|
def process_block(state: BeaconState, block: BeaconBlock) -> None:
|
||||||
process_block_header(state, block)
|
process_block_header(state, block)
|
||||||
if is_execution_enabled(state, block.body):
|
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_randao(state, block.body)
|
||||||
process_eth1_data(state, block.body)
|
process_eth1_data(state, block.body)
|
||||||
process_operations(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)
|
assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)
|
||||||
# Verify the execution payload is valid
|
# Verify the execution payload is valid
|
||||||
assert execution_engine.notify_new_payload(payload)
|
assert execution_engine.notify_new_payload(payload)
|
||||||
|
|
||||||
# Cache execution payload header
|
# Cache execution payload header
|
||||||
state.latest_execution_payload_header = ExecutionPayloadHeader(
|
state.latest_execution_payload_header = ExecutionPayloadHeader(
|
||||||
parent_hash=payload.parent_hash,
|
parent_hash=payload.parent_hash,
|
||||||
|
@ -267,9 +273,10 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe
|
||||||
timestamp=payload.timestamp,
|
timestamp=payload.timestamp,
|
||||||
extra_data=payload.extra_data,
|
extra_data=payload.extra_data,
|
||||||
base_fee_per_gas=payload.base_fee_per_gas,
|
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,
|
block_hash=payload.block_hash,
|
||||||
transactions_root=hash_tree_root(payload.transactions),
|
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
|
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.
|
||||||
|
|
|
@ -44,6 +44,8 @@ def compute_fork_version(epoch: Epoch) -> Version:
|
||||||
"""
|
"""
|
||||||
if epoch >= EIP4844_FORK_EPOCH:
|
if epoch >= EIP4844_FORK_EPOCH:
|
||||||
return EIP4844_FORK_VERSION
|
return EIP4844_FORK_VERSION
|
||||||
|
if epoch >= CAPELLA_FORK_EPOCH:
|
||||||
|
return CAPELLA_FORK_VERSION
|
||||||
if epoch >= BELLATRIX_FORK_EPOCH:
|
if epoch >= BELLATRIX_FORK_EPOCH:
|
||||||
return BELLATRIX_FORK_VERSION
|
return BELLATRIX_FORK_VERSION
|
||||||
if epoch >= ALTAIR_FORK_EPOCH:
|
if epoch >= ALTAIR_FORK_EPOCH:
|
||||||
|
@ -62,12 +64,29 @@ Note that for the pure EIP-4844 networks, we don't apply `upgrade_to_eip4844` si
|
||||||
|
|
||||||
### Upgrading the state
|
### 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
|
```python
|
||||||
def upgrade_to_eip4844(pre: bellatrix.BeaconState) -> BeaconState:
|
def upgrade_to_eip4844(pre: capella.BeaconState) -> BeaconState:
|
||||||
# TODO: if Capella gets scheduled, add sync it with Capella.BeaconState
|
epoch = capella.get_current_epoch(pre)
|
||||||
epoch = bellatrix.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,
|
||||||
|
state_root=pre.latest_execution_payload_header.state_root,
|
||||||
|
receipts_root=pre.latest_execution_payload_header.receipts_root,
|
||||||
|
logs_bloom=pre.latest_execution_payload_header.logs_bloom,
|
||||||
|
prev_randao=pre.latest_execution_payload_header.prev_randao,
|
||||||
|
block_number=pre.latest_execution_payload_header.block_number,
|
||||||
|
gas_limit=pre.latest_execution_payload_header.gas_limit,
|
||||||
|
gas_used=pre.latest_execution_payload_header.gas_used,
|
||||||
|
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]
|
||||||
|
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,
|
||||||
|
)
|
||||||
post = BeaconState(
|
post = BeaconState(
|
||||||
# Versioning
|
# Versioning
|
||||||
genesis_time=pre.genesis_time,
|
genesis_time=pre.genesis_time,
|
||||||
|
@ -108,7 +127,10 @@ def upgrade_to_eip4844(pre: bellatrix.BeaconState) -> BeaconState:
|
||||||
current_sync_committee=pre.current_sync_committee,
|
current_sync_committee=pre.current_sync_committee,
|
||||||
next_sync_committee=pre.next_sync_committee,
|
next_sync_committee=pre.next_sync_committee,
|
||||||
# Execution-layer
|
# Execution-layer
|
||||||
latest_execution_payload_header=pre.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
|
return post
|
||||||
|
|
|
@ -17,12 +17,14 @@ The specification of these changes continues in the same format as the network s
|
||||||
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub)
|
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub)
|
||||||
- [Topics and messages](#topics-and-messages)
|
- [Topics and messages](#topics-and-messages)
|
||||||
- [Global topics](#global-topics)
|
- [Global topics](#global-topics)
|
||||||
|
- [`beacon_block`](#beacon_block)
|
||||||
- [`beacon_block_and_blobs_sidecar`](#beacon_block_and_blobs_sidecar)
|
- [`beacon_block_and_blobs_sidecar`](#beacon_block_and_blobs_sidecar)
|
||||||
- [Transitioning the gossip](#transitioning-the-gossip)
|
- [Transitioning the gossip](#transitioning-the-gossip)
|
||||||
- [The Req/Resp domain](#the-reqresp-domain)
|
- [The Req/Resp domain](#the-reqresp-domain)
|
||||||
- [Messages](#messages)
|
- [Messages](#messages)
|
||||||
- [BeaconBlocksByRange v2](#beaconblocksbyrange-v2)
|
- [BeaconBlocksByRange v2](#beaconblocksbyrange-v2)
|
||||||
- [BeaconBlocksByRoot v2](#beaconblocksbyroot-v2)
|
- [BeaconBlocksByRoot v2](#beaconblocksbyroot-v2)
|
||||||
|
- [BeaconBlockAndBlobsSidecarByRoot v1](#beaconblockandblobssidecarbyroot-v1)
|
||||||
- [BlobsSidecarsByRange v1](#blobssidecarsbyrange-v1)
|
- [BlobsSidecarsByRange v1](#blobssidecarsbyrange-v1)
|
||||||
- [Design decision rationale](#design-decision-rationale)
|
- [Design decision rationale](#design-decision-rationale)
|
||||||
- [Why are blobs relayed as a sidecar, separate from beacon blocks?](#why-are-blobs-relayed-as-a-sidecar-separate-from-beacon-blocks)
|
- [Why are blobs relayed as a sidecar, separate from beacon blocks?](#why-are-blobs-relayed-as-a-sidecar-separate-from-beacon-blocks)
|
||||||
|
@ -64,9 +66,9 @@ Some gossip meshes are upgraded in the fork of EIP4844 to support upgraded types
|
||||||
### Topics and messages
|
### Topics and messages
|
||||||
|
|
||||||
Topics follow the same specification as in prior upgrades.
|
Topics follow the same specification as in prior upgrades.
|
||||||
All topics remain stable except the beacon block topic which is updated with the modified type.
|
The `beacon_block` topic is deprecated and replaced by the `beacon_block_and_blobs_sidecar` topic. All other topics remain stable.
|
||||||
|
|
||||||
The specification around the creation, validation, and dissemination of messages has not changed from the Bellatrix document unless explicitly noted here.
|
The specification around the creation, validation, and dissemination of messages has not changed from the Capella document unless explicitly noted here.
|
||||||
|
|
||||||
The derivation of the `message-id` remains stable.
|
The derivation of the `message-id` remains stable.
|
||||||
|
|
||||||
|
@ -81,11 +83,19 @@ The new topics along with the type of the `data` field of a gossipsub message ar
|
||||||
|
|
||||||
EIP4844 introduces a new global topic for beacon block and blobs-sidecars.
|
EIP4844 introduces a new global topic for beacon block and blobs-sidecars.
|
||||||
|
|
||||||
|
##### `beacon_block`
|
||||||
|
|
||||||
|
This topic is deprecated and clients **MUST NOT** expose in their topic set to any peer. Implementers do not need to do
|
||||||
|
anything beyond simply skip implementation, and it is explicitly called out as it is a departure from previous versioning
|
||||||
|
of this topic.
|
||||||
|
|
||||||
|
Refer to [the section below](#transitioning-the-gossip) for details on how to transition the gossip.
|
||||||
|
|
||||||
##### `beacon_block_and_blobs_sidecar`
|
##### `beacon_block_and_blobs_sidecar`
|
||||||
|
|
||||||
This topic is used to propagate new signed and coupled beacon blocks and blobs sidecars to all nodes on the networks.
|
This topic is used to propagate new signed and coupled beacon blocks and blobs sidecars to all nodes on the networks.
|
||||||
|
|
||||||
In addition to the gossip validations for the `beacon_block` topic from prior specifications, the following validations MUST pass before forwarding the `signed_beacon_block_and_blobs_sidecar` on the network.
|
In addition to the gossip validations for the `beacon_block` topic from prior specifications, the following validations MUST pass before forwarding the `signed_beacon_block_and_blobs_sidecar` on the network.
|
||||||
Alias `signed_beacon_block = signed_beacon_block_and_blobs_sidecar.beacon_block`, `block = signed_beacon_block.message`, `execution_payload = block.body.execution_payload`.
|
Alias `signed_beacon_block = signed_beacon_block_and_blobs_sidecar.beacon_block`, `block = signed_beacon_block.message`, `execution_payload = block.body.execution_payload`.
|
||||||
- _[REJECT]_ The KZG commitments of the blobs are all correctly encoded compressed BLS G1 Points.
|
- _[REJECT]_ The KZG commitments of the blobs are all correctly encoded compressed BLS G1 Points.
|
||||||
-- i.e. `all(bls.KeyValidate(commitment) for commitment in block.body.blob_kzg_commitments)`
|
-- i.e. `all(bls.KeyValidate(commitment) for commitment in block.body.blob_kzg_commitments)`
|
||||||
|
@ -96,8 +106,8 @@ Alias `sidecar = signed_beacon_block_and_blobs_sidecar.blobs_sidecar`.
|
||||||
- _[IGNORE]_ the `sidecar.beacon_block_slot` is for the current slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) -- i.e. `sidecar.beacon_block_slot == block.slot`.
|
- _[IGNORE]_ the `sidecar.beacon_block_slot` is for the current slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) -- i.e. `sidecar.beacon_block_slot == block.slot`.
|
||||||
- _[REJECT]_ the `sidecar.blobs` are all well formatted, i.e. the `BLSFieldElement` in valid range (`x < BLS_MODULUS`).
|
- _[REJECT]_ the `sidecar.blobs` are all well formatted, i.e. the `BLSFieldElement` in valid range (`x < BLS_MODULUS`).
|
||||||
- _[REJECT]_ The KZG proof is a correctly encoded compressed BLS G1 Point -- i.e. `bls.KeyValidate(blobs_sidecar.kzg_aggregated_proof)`
|
- _[REJECT]_ The KZG proof is a correctly encoded compressed BLS G1 Point -- i.e. `bls.KeyValidate(blobs_sidecar.kzg_aggregated_proof)`
|
||||||
|
- _[REJECT]_ The KZG commitments in the block are valid against the provided blobs sidecar.
|
||||||
Once the sidecar and beacon block are received together, `validate_blobs_sidecar` can unlock the data-availability fork-choice dependency.
|
-- i.e. `validate_blobs_sidecar(block.slot, hash_tree_root(block), block.body.blob_kzg_commitments, sidecar)`
|
||||||
|
|
||||||
### Transitioning the gossip
|
### Transitioning the gossip
|
||||||
|
|
||||||
|
@ -123,13 +133,15 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||||
|
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
|
||||||
| `EIP4844_FORK_VERSION` | `eip4844.SignedBeaconBlock` |
|
| `EIP4844_FORK_VERSION` | `eip4844.SignedBeaconBlock` |
|
||||||
|
|
||||||
#### BeaconBlocksByRoot v2
|
#### BeaconBlocksByRoot v2
|
||||||
|
|
||||||
**Protocol ID:** `/eth2/beacon_chain/req/beacon_blocks_by_root/2/`
|
**Protocol ID:** `/eth2/beacon_chain/req/beacon_blocks_by_root/2/`
|
||||||
|
|
||||||
The EIP-4844 fork-digest is introduced to the `context` enum to specify EIP-4844 beacon block type.
|
After `EIP4844_FORK_EPOCH`, `BeaconBlocksByRootV2` is replaced by `BeaconBlockAndBlobsSidecarByRootV1`
|
||||||
|
clients MUST support requesting blocks by root for pre-fork-epoch blocks.
|
||||||
|
|
||||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||||
|
|
||||||
|
@ -140,7 +152,43 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||||
| `EIP4844_FORK_VERSION` | `eip4844.SignedBeaconBlock` |
|
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
|
||||||
|
|
||||||
|
#### BeaconBlockAndBlobsSidecarByRoot v1
|
||||||
|
|
||||||
|
**Protocol ID:** `/eth2/beacon_chain/req/beacon_block_and_blobs_sidecar_by_root/1/`
|
||||||
|
|
||||||
|
Request Content:
|
||||||
|
|
||||||
|
```
|
||||||
|
(
|
||||||
|
List[Root, MAX_REQUEST_BLOCKS]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Response Content:
|
||||||
|
|
||||||
|
```
|
||||||
|
(
|
||||||
|
List[SignedBeaconBlockAndBlobsSidecar, MAX_REQUEST_BLOCKS]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Requests blocks by block root (= `hash_tree_root(SignedBeaconBlockAndBlobsSidecar.beacon_block.message)`).
|
||||||
|
The response is a list of `SignedBeaconBlockAndBlobsSidecar` whose length is less than or equal to the number of requests.
|
||||||
|
It may be less in the case that the responding peer is missing blocks and sidecars.
|
||||||
|
|
||||||
|
No more than `MAX_REQUEST_BLOCKS` may be requested at a time.
|
||||||
|
|
||||||
|
`BeaconBlockAndBlobsSidecarByRoot` is primarily used to recover recent blocks and sidecars (e.g. when receiving a block or attestation whose parent is unknown).
|
||||||
|
|
||||||
|
The response MUST consist of zero or more `response_chunk`.
|
||||||
|
Each _successful_ `response_chunk` MUST contain a single `SignedBeaconBlockAndBlobsSidecar` payload.
|
||||||
|
|
||||||
|
Clients MUST support requesting blocks and sidecars since the latest finalized epoch.
|
||||||
|
|
||||||
|
Clients MUST respond with at least one block and sidecar, if they have it.
|
||||||
|
Clients MAY limit the number of blocks and sidecars in the response.
|
||||||
|
|
||||||
#### BlobsSidecarsByRange v1
|
#### BlobsSidecarsByRange v1
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
- [KZG](#kzg)
|
- [KZG](#kzg)
|
||||||
- [`blob_to_kzg_commitment`](#blob_to_kzg_commitment)
|
- [`blob_to_kzg_commitment`](#blob_to_kzg_commitment)
|
||||||
- [`verify_kzg_proof`](#verify_kzg_proof)
|
- [`verify_kzg_proof`](#verify_kzg_proof)
|
||||||
|
- [`verify_kzg_proof_impl`](#verify_kzg_proof_impl)
|
||||||
- [`compute_kzg_proof`](#compute_kzg_proof)
|
- [`compute_kzg_proof`](#compute_kzg_proof)
|
||||||
- [`compute_aggregated_poly_and_commitment`](#compute_aggregated_poly_and_commitment)
|
- [`compute_aggregated_poly_and_commitment`](#compute_aggregated_poly_and_commitment)
|
||||||
- [`compute_aggregate_kzg_proof`](#compute_aggregate_kzg_proof)
|
- [`compute_aggregate_kzg_proof`](#compute_aggregate_kzg_proof)
|
||||||
|
@ -45,6 +46,8 @@
|
||||||
|
|
||||||
This document specifies basic polynomial operations and KZG polynomial commitment operations as they are needed for the EIP-4844 specification. The implementations are not optimized for performance, but readability. All practical implementations should optimize the polynomial operations.
|
This document specifies basic polynomial operations and KZG polynomial commitment operations as they are needed for the EIP-4844 specification. The implementations are not optimized for performance, but readability. All practical implementations should optimize the polynomial operations.
|
||||||
|
|
||||||
|
Functions flagged as "Public method" MUST be provided by the underlying KZG library as public functions. All other functions are private functions used internally by the KZG library.
|
||||||
|
|
||||||
## Custom types
|
## Custom types
|
||||||
|
|
||||||
| Name | SSZ equivalent | Description |
|
| Name | SSZ equivalent | Description |
|
||||||
|
@ -276,7 +279,7 @@ def evaluate_polynomial_in_evaluation_form(polynomial: Polynomial,
|
||||||
|
|
||||||
result = 0
|
result = 0
|
||||||
for i in range(width):
|
for i in range(width):
|
||||||
result += div(int(polynomial[i]) * int(roots_of_unity_brp[i]), (int(z) - roots_of_unity_brp[i]))
|
result += div(int(polynomial[i]) * int(roots_of_unity_brp[i]), (int(z) - int(roots_of_unity_brp[i])))
|
||||||
result = result * (pow(z, width, BLS_MODULUS) - 1) * inverse_width % BLS_MODULUS
|
result = result * (pow(z, width, BLS_MODULUS) - 1) * inverse_width % BLS_MODULUS
|
||||||
return result
|
return result
|
||||||
```
|
```
|
||||||
|
@ -289,6 +292,9 @@ KZG core functions. These are also defined in EIP-4844 execution specs.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def blob_to_kzg_commitment(blob: Blob) -> KZGCommitment:
|
def blob_to_kzg_commitment(blob: Blob) -> KZGCommitment:
|
||||||
|
"""
|
||||||
|
Public method.
|
||||||
|
"""
|
||||||
return g1_lincomb(bit_reversal_permutation(KZG_SETUP_LAGRANGE), blob_to_polynomial(blob))
|
return g1_lincomb(bit_reversal_permutation(KZG_SETUP_LAGRANGE), blob_to_polynomial(blob))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -296,11 +302,27 @@ def blob_to_kzg_commitment(blob: Blob) -> KZGCommitment:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def verify_kzg_proof(polynomial_kzg: KZGCommitment,
|
def verify_kzg_proof(polynomial_kzg: KZGCommitment,
|
||||||
z: BLSFieldElement,
|
z: Bytes32,
|
||||||
y: BLSFieldElement,
|
y: Bytes32,
|
||||||
kzg_proof: KZGProof) -> bool:
|
kzg_proof: KZGProof) -> bool:
|
||||||
"""
|
"""
|
||||||
Verify KZG proof that ``p(z) == y`` where ``p(z)`` is the polynomial represented by ``polynomial_kzg``.
|
Verify KZG proof that ``p(z) == y`` where ``p(z)`` is the polynomial represented by ``polynomial_kzg``.
|
||||||
|
Receives inputs as bytes.
|
||||||
|
Public method.
|
||||||
|
"""
|
||||||
|
return verify_kzg_proof_impl(polynomial_kzg, bytes_to_bls_field(z), bytes_to_bls_field(y), kzg_proof)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### `verify_kzg_proof_impl`
|
||||||
|
|
||||||
|
```python
|
||||||
|
def verify_kzg_proof_impl(polynomial_kzg: KZGCommitment,
|
||||||
|
z: BLSFieldElement,
|
||||||
|
y: BLSFieldElement,
|
||||||
|
kzg_proof: KZGProof) -> bool:
|
||||||
|
"""
|
||||||
|
Verify KZG proof that ``p(z) == y`` where ``p(z)`` is the polynomial represented by ``polynomial_kzg``.
|
||||||
"""
|
"""
|
||||||
# Verify: P - y = Q * (X - z)
|
# Verify: P - y = Q * (X - z)
|
||||||
X_minus_z = bls.add(bls.bytes96_to_G2(KZG_SETUP_G2[1]), bls.multiply(bls.G2, BLS_MODULUS - z))
|
X_minus_z = bls.add(bls.bytes96_to_G2(KZG_SETUP_G2[1]), bls.multiply(bls.G2, BLS_MODULUS - z))
|
||||||
|
@ -367,6 +389,9 @@ def compute_aggregated_poly_and_commitment(
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def compute_aggregate_kzg_proof(blobs: Sequence[Blob]) -> KZGProof:
|
def compute_aggregate_kzg_proof(blobs: Sequence[Blob]) -> KZGProof:
|
||||||
|
"""
|
||||||
|
Public method.
|
||||||
|
"""
|
||||||
commitments = [blob_to_kzg_commitment(blob) for blob in blobs]
|
commitments = [blob_to_kzg_commitment(blob) for blob in blobs]
|
||||||
aggregated_poly, aggregated_poly_commitment, evaluation_challenge = compute_aggregated_poly_and_commitment(
|
aggregated_poly, aggregated_poly_commitment, evaluation_challenge = compute_aggregated_poly_and_commitment(
|
||||||
blobs,
|
blobs,
|
||||||
|
@ -381,6 +406,9 @@ def compute_aggregate_kzg_proof(blobs: Sequence[Blob]) -> KZGProof:
|
||||||
def verify_aggregate_kzg_proof(blobs: Sequence[Blob],
|
def verify_aggregate_kzg_proof(blobs: Sequence[Blob],
|
||||||
expected_kzg_commitments: Sequence[KZGCommitment],
|
expected_kzg_commitments: Sequence[KZGCommitment],
|
||||||
kzg_aggregated_proof: KZGCommitment) -> bool:
|
kzg_aggregated_proof: KZGCommitment) -> bool:
|
||||||
|
"""
|
||||||
|
Public method.
|
||||||
|
"""
|
||||||
aggregated_poly, aggregated_poly_commitment, evaluation_challenge = compute_aggregated_poly_and_commitment(
|
aggregated_poly, aggregated_poly_commitment, evaluation_challenge = compute_aggregated_poly_and_commitment(
|
||||||
blobs,
|
blobs,
|
||||||
expected_kzg_commitments,
|
expected_kzg_commitments,
|
||||||
|
@ -390,5 +418,5 @@ def verify_aggregate_kzg_proof(blobs: Sequence[Blob],
|
||||||
y = evaluate_polynomial_in_evaluation_form(aggregated_poly, evaluation_challenge)
|
y = evaluate_polynomial_in_evaluation_form(aggregated_poly, evaluation_challenge)
|
||||||
|
|
||||||
# Verify aggregated proof
|
# Verify aggregated proof
|
||||||
return verify_kzg_proof(aggregated_poly_commitment, evaluation_challenge, y, kzg_aggregated_proof)
|
return verify_kzg_proof_impl(aggregated_poly_commitment, evaluation_challenge, y, kzg_aggregated_proof)
|
||||||
```
|
```
|
||||||
|
|
|
@ -29,7 +29,7 @@ This document represents the changes to be made in the code of an "honest valida
|
||||||
|
|
||||||
## Prerequisites
|
## 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 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.
|
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
|
##### 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)`.
|
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`:
|
2. Validate `blobs` and `blob_kzg_commitments`:
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.3.0-alpha.0
|
1.3.0-alpha.1
|
||||||
|
|
|
@ -4,7 +4,6 @@ import time
|
||||||
import shutil
|
import shutil
|
||||||
import argparse
|
import argparse
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from filelock import FileLock
|
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
from typing import Iterable, AnyStr, Any, Callable
|
from typing import Iterable, AnyStr, Any, Callable
|
||||||
|
@ -13,6 +12,7 @@ from ruamel.yaml import (
|
||||||
YAML,
|
YAML,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from filelock import FileLock
|
||||||
from snappy import compress
|
from snappy import compress
|
||||||
|
|
||||||
from eth2spec.test import context
|
from eth2spec.test import context
|
||||||
|
@ -141,6 +141,10 @@ def run_generator(generator_name, test_providers: Iterable[TestProvider]):
|
||||||
tprov.prepare()
|
tprov.prepare()
|
||||||
|
|
||||||
for test_case in tprov.make_cases():
|
for test_case in tprov.make_cases():
|
||||||
|
# If preset list is assigned, filter by presets.
|
||||||
|
if len(presets) != 0 and test_case.preset_name not in presets:
|
||||||
|
continue
|
||||||
|
|
||||||
case_dir = (
|
case_dir = (
|
||||||
Path(output_dir) / Path(test_case.preset_name) / Path(test_case.fork_name)
|
Path(output_dir) / Path(test_case.preset_name) / Path(test_case.fork_name)
|
||||||
/ Path(test_case.runner_name) / Path(test_case.handler_name)
|
/ Path(test_case.runner_name) / Path(test_case.handler_name)
|
||||||
|
@ -179,7 +183,16 @@ def run_generator(generator_name, test_providers: Iterable[TestProvider]):
|
||||||
try:
|
try:
|
||||||
fn(case_dir)
|
fn(case_dir)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
sys.exit(f'Error when dumping test "{case_dir}", part "{name}", kind "{out_kind}": {e}')
|
error_message = (
|
||||||
|
f'[Error] error when dumping test "{case_dir}", part "{name}", kind "{out_kind}": {e}'
|
||||||
|
)
|
||||||
|
# Write to error log file
|
||||||
|
with log_file.open("a+") as f:
|
||||||
|
f.write(error_message)
|
||||||
|
traceback.print_exc(file=f)
|
||||||
|
f.write('\n')
|
||||||
|
|
||||||
|
sys.exit(error_message)
|
||||||
|
|
||||||
meta = dict()
|
meta = dict()
|
||||||
|
|
||||||
|
@ -210,13 +223,13 @@ def run_generator(generator_name, test_providers: Iterable[TestProvider]):
|
||||||
if not written_part:
|
if not written_part:
|
||||||
print(f"test case {case_dir} did not produce any test case parts")
|
print(f"test case {case_dir} did not produce any test case parts")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"ERROR: failed to generate vector(s) for test {case_dir}: {e}")
|
error_message = f"[ERROR] failed to generate vector(s) for test {case_dir}: {e}"
|
||||||
traceback.print_exc()
|
# Write to error log file
|
||||||
# Write to log file
|
|
||||||
with log_file.open("a+") as f:
|
with log_file.open("a+") as f:
|
||||||
f.write(f"ERROR: failed to generate vector(s) for test {case_dir}: {e}")
|
f.write(error_message)
|
||||||
traceback.print_exc(file=f)
|
traceback.print_exc(file=f)
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
|
traceback.print_exc()
|
||||||
else:
|
else:
|
||||||
# If no written_part, the only file was incomplete_tag_file. Clear the existing case_dir folder.
|
# If no written_part, the only file was incomplete_tag_file. Clear the existing case_dir folder.
|
||||||
if not written_part:
|
if not written_part:
|
||||||
|
|
|
@ -49,7 +49,7 @@ def generate_from_tests(runner_name: str, handler_name: str, src: Any,
|
||||||
preset_name=preset_name,
|
preset_name=preset_name,
|
||||||
runner_name=runner_name,
|
runner_name=runner_name,
|
||||||
handler_name=handler_name,
|
handler_name=handler_name,
|
||||||
suite_name='pyspec_tests',
|
suite_name=getattr(tfn, 'suite_name', 'pyspec_tests'),
|
||||||
case_name=case_name,
|
case_name=case_name,
|
||||||
# TODO: with_all_phases and other per-phase tooling, should be replaced with per-fork equivalent.
|
# TODO: with_all_phases and other per-phase tooling, should be replaced with per-fork equivalent.
|
||||||
case_fn=lambda: tfn(generator_mode=True, phase=phase, preset=preset_name, bls_active=bls_active)
|
case_fn=lambda: tfn(generator_mode=True, phase=phase, preset=preset_name, bls_active=bls_active)
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
from eth2spec.test.context import (
|
from eth2spec.test.context import (
|
||||||
spec_state_test,
|
spec_state_test,
|
||||||
with_altair_and_later,
|
with_altair_and_later,
|
||||||
|
with_test_suite_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@with_test_suite_name("BeaconState")
|
||||||
@with_altair_and_later
|
@with_altair_and_later
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_current_sync_committee_merkle_proof(spec, state):
|
def test_current_sync_committee_merkle_proof(spec, state):
|
||||||
yield "state", state
|
yield "object", state
|
||||||
current_sync_committee_branch = spec.compute_merkle_proof_for_state(state, spec.CURRENT_SYNC_COMMITTEE_INDEX)
|
current_sync_committee_branch = \
|
||||||
|
spec.compute_merkle_proof_for_state(state, spec.CURRENT_SYNC_COMMITTEE_INDEX)
|
||||||
yield "proof", {
|
yield "proof", {
|
||||||
"leaf": "0x" + state.current_sync_committee.hash_tree_root().hex(),
|
"leaf": "0x" + state.current_sync_committee.hash_tree_root().hex(),
|
||||||
"leaf_index": spec.CURRENT_SYNC_COMMITTEE_INDEX,
|
"leaf_index": spec.CURRENT_SYNC_COMMITTEE_INDEX,
|
||||||
|
@ -23,11 +26,13 @@ def test_current_sync_committee_merkle_proof(spec, state):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@with_test_suite_name("BeaconState")
|
||||||
@with_altair_and_later
|
@with_altair_and_later
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_next_sync_committee_merkle_proof(spec, state):
|
def test_next_sync_committee_merkle_proof(spec, state):
|
||||||
yield "state", state
|
yield "object", state
|
||||||
next_sync_committee_branch = spec.compute_merkle_proof_for_state(state, spec.NEXT_SYNC_COMMITTEE_INDEX)
|
next_sync_committee_branch = \
|
||||||
|
spec.compute_merkle_proof_for_state(state, spec.NEXT_SYNC_COMMITTEE_INDEX)
|
||||||
yield "proof", {
|
yield "proof", {
|
||||||
"leaf": "0x" + state.next_sync_committee.hash_tree_root().hex(),
|
"leaf": "0x" + state.next_sync_committee.hash_tree_root().hex(),
|
||||||
"leaf_index": spec.NEXT_SYNC_COMMITTEE_INDEX,
|
"leaf_index": spec.NEXT_SYNC_COMMITTEE_INDEX,
|
||||||
|
@ -42,11 +47,13 @@ def test_next_sync_committee_merkle_proof(spec, state):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@with_test_suite_name("BeaconState")
|
||||||
@with_altair_and_later
|
@with_altair_and_later
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_finality_root_merkle_proof(spec, state):
|
def test_finality_root_merkle_proof(spec, state):
|
||||||
yield "state", state
|
yield "object", state
|
||||||
finality_branch = spec.compute_merkle_proof_for_state(state, spec.FINALIZED_ROOT_INDEX)
|
finality_branch = \
|
||||||
|
spec.compute_merkle_proof_for_state(state, spec.FINALIZED_ROOT_INDEX)
|
||||||
yield "proof", {
|
yield "proof", {
|
||||||
"leaf": "0x" + state.finalized_checkpoint.root.hex(),
|
"leaf": "0x" + state.finalized_checkpoint.root.hex(),
|
||||||
"leaf_index": spec.FINALIZED_ROOT_INDEX,
|
"leaf_index": spec.FINALIZED_ROOT_INDEX,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
from eth2spec.test.helpers.constants import CAPELLA
|
||||||
from eth2spec.test.helpers.keys import pubkeys
|
from eth2spec.test.helpers.keys import pubkeys
|
||||||
from eth2spec.test.helpers.bls_to_execution_changes import get_signed_address_change
|
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):
|
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
|
yield 'post', state
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success(spec, state):
|
def test_success(spec, state):
|
||||||
signed_address_change = get_signed_address_change(spec, state)
|
signed_address_change = get_signed_address_change(spec, state)
|
||||||
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change)
|
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_not_activated(spec, state):
|
def test_success_not_activated(spec, state):
|
||||||
validator_index = 3
|
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))
|
assert not spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_in_activation_queue(spec, state):
|
def test_success_in_activation_queue(spec, state):
|
||||||
validator_index = 3
|
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))
|
assert not spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_in_exit_queue(spec, state):
|
def test_success_in_exit_queue(spec, state):
|
||||||
validator_index = 3
|
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)
|
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_exited(spec, state):
|
def test_success_exited(spec, state):
|
||||||
validator_index = 4
|
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))
|
assert not spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_withdrawable(spec, state):
|
def test_success_withdrawable(spec, state):
|
||||||
validator_index = 4
|
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))
|
assert spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_val_index_out_of_range(spec, state):
|
def test_fail_val_index_out_of_range(spec, state):
|
||||||
# Create for one validator beyond the validator list length
|
# 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)
|
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
|
@spec_state_test
|
||||||
def test_fail_already_0x01(spec, state):
|
def test_fail_already_0x01(spec, state):
|
||||||
# Create for one validator beyond the validator list length
|
# 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)
|
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
|
@spec_state_test
|
||||||
def test_fail_incorrect_from_bls_pubkey(spec, state):
|
def test_fail_incorrect_from_bls_pubkey(spec, state):
|
||||||
# Create for one validator beyond the validator list length
|
# 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)
|
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
|
@spec_state_test
|
||||||
@always_bls
|
@always_bls
|
||||||
def test_fail_bad_signature(spec, state):
|
def test_fail_bad_signature(spec, state):
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
from eth2spec.test.context import (
|
from eth2spec.test.context import (
|
||||||
spec_state_test,
|
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.state import next_epoch_via_block
|
||||||
from eth2spec.test.helpers.deposits import (
|
from eth2spec.test.helpers.deposits import (
|
||||||
prepare_state_and_deposit,
|
prepare_state_and_deposit,
|
||||||
|
@ -10,7 +11,7 @@ from eth2spec.test.helpers.deposits import (
|
||||||
from eth2spec.test.helpers.withdrawals import set_validator_fully_withdrawable
|
from eth2spec.test.helpers.withdrawals import set_validator_fully_withdrawable
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_top_up_to_withdrawn_validator(spec, state):
|
def test_success_top_up_to_withdrawn_validator(spec, state):
|
||||||
validator_index = 0
|
validator_index = 0
|
||||||
|
|
|
@ -3,10 +3,10 @@ import random
|
||||||
from eth2spec.test.context import (
|
from eth2spec.test.context import (
|
||||||
spec_state_test,
|
spec_state_test,
|
||||||
expect_assertion_error,
|
expect_assertion_error,
|
||||||
with_capella_and_later,
|
|
||||||
with_presets,
|
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 (
|
from eth2spec.test.helpers.execution_payload import (
|
||||||
build_empty_execution_payload,
|
build_empty_execution_payload,
|
||||||
)
|
)
|
||||||
|
@ -87,7 +87,7 @@ def run_withdrawals_processing(spec, state, execution_payload, num_expected_with
|
||||||
return expected_withdrawals
|
return expected_withdrawals
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_zero_expected_withdrawals(spec, state):
|
def test_success_zero_expected_withdrawals(spec, state):
|
||||||
assert len(spec.get_expected_withdrawals(state)) == 0
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_one_full_withdrawal(spec, state):
|
def test_success_one_full_withdrawal(spec, state):
|
||||||
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
|
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)
|
partial_withdrawals_indices=partial_withdrawals_indices)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_one_partial_withdrawal(spec, state):
|
def test_success_one_partial_withdrawal(spec, state):
|
||||||
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
|
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
|
@spec_state_test
|
||||||
def test_success_max_per_slot(spec, state):
|
def test_success_max_per_slot(spec, state):
|
||||||
num_full_withdrawals = spec.MAX_WITHDRAWALS_PER_PAYLOAD // 2
|
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)
|
partial_withdrawals_indices=partial_withdrawals_indices)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_all_fully_withdrawable(spec, state):
|
def test_success_all_fully_withdrawable(spec, state):
|
||||||
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
|
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)
|
partial_withdrawals_indices=partial_withdrawals_indices)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_all_partially_withdrawable(spec, state):
|
def test_success_all_partially_withdrawable(spec, state):
|
||||||
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
|
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
|
# Failure cases in which the number of withdrawals in the execution_payload is incorrect
|
||||||
#
|
#
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_non_withdrawable_non_empty_withdrawals(spec, state):
|
def test_fail_non_withdrawable_non_empty_withdrawals(spec, state):
|
||||||
next_slot(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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_one_expected_full_withdrawal_and_none_in_withdrawals(spec, state):
|
def test_fail_one_expected_full_withdrawal_and_none_in_withdrawals(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_one_expected_partial_withdrawal_and_none_in_withdrawals(spec, state):
|
def test_fail_one_expected_partial_withdrawal_and_none_in_withdrawals(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=1)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_one_expected_full_withdrawal_and_duplicate_in_withdrawals(spec, state):
|
def test_fail_one_expected_full_withdrawal_and_duplicate_in_withdrawals(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_full_withdrawals=2)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_two_expected_partial_withdrawal_and_duplicate_in_withdrawals(spec, state):
|
def test_fail_two_expected_partial_withdrawal_and_duplicate_in_withdrawals(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=2)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_max_per_slot_full_withdrawals_and_one_less_in_withdrawals(spec, state):
|
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)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_max_per_slot_partial_withdrawals_and_one_less_in_withdrawals(spec, state):
|
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)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_a_lot_fully_withdrawable_too_few_in_withdrawals(spec, state):
|
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)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_a_lot_partially_withdrawable_too_few_in_withdrawals(spec, state):
|
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)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_a_lot_mixed_withdrawable_in_queue_too_few_in_withdrawals(spec, state):
|
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,
|
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
|
# Failure cases in which the withdrawals in the execution_payload are incorrect
|
||||||
#
|
#
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_incorrect_withdrawal_index(spec, state):
|
def test_fail_incorrect_withdrawal_index(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_incorrect_address_full(spec, state):
|
def test_fail_incorrect_address_full(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_incorrect_address_partial(spec, state):
|
def test_fail_incorrect_address_partial(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=1)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_incorrect_amount_full(spec, state):
|
def test_fail_incorrect_amount_full(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_incorrect_amount_partial(spec, state):
|
def test_fail_incorrect_amount_partial(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_full_withdrawals=1)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_one_of_many_incorrectly_full(spec, state):
|
def test_fail_one_of_many_incorrectly_full(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_one_of_many_incorrectly_partial(spec, state):
|
def test_fail_one_of_many_incorrectly_partial(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_many_incorrectly_full(spec, state):
|
def test_fail_many_incorrectly_full(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_full_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, valid=False)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_fail_many_incorrectly_partial(spec, state):
|
def test_fail_many_incorrectly_partial(spec, state):
|
||||||
prepare_expected_withdrawals(spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4)
|
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
|
# More full withdrawal cases
|
||||||
#
|
#
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_withdrawable_epoch_but_0_balance(spec, state):
|
def test_withdrawable_epoch_but_0_balance(spec, state):
|
||||||
current_epoch = spec.get_current_epoch(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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_withdrawable_epoch_but_0_effective_balance_0_balance(spec, state):
|
def test_withdrawable_epoch_but_0_effective_balance_0_balance(spec, state):
|
||||||
current_epoch = spec.get_current_epoch(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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_withdrawable_epoch_but_0_effective_balance_nonzero_balance(spec, state):
|
def test_withdrawable_epoch_but_0_effective_balance_nonzero_balance(spec, state):
|
||||||
current_epoch = spec.get_current_epoch(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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_no_withdrawals_but_some_next_epoch(spec, state):
|
def test_no_withdrawals_but_some_next_epoch(spec, state):
|
||||||
current_epoch = spec.get_current_epoch(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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_all_withdrawal(spec, state):
|
def test_all_withdrawal(spec, state):
|
||||||
# Make all validators withdrawable
|
# 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)
|
yield from run_withdrawals_processing(spec, state, execution_payload)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_random_full_withdrawals_0(spec, state):
|
def test_random_full_withdrawals_0(spec, state):
|
||||||
yield from run_random_full_withdrawals_test(spec, state, random.Random(444))
|
yield from run_random_full_withdrawals_test(spec, state, random.Random(444))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_random_full_withdrawals_1(spec, state):
|
def test_random_full_withdrawals_1(spec, state):
|
||||||
yield from run_random_full_withdrawals_test(spec, state, random.Random(420))
|
yield from run_random_full_withdrawals_test(spec, state, random.Random(420))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_random_full_withdrawals_2(spec, state):
|
def test_random_full_withdrawals_2(spec, state):
|
||||||
yield from run_random_full_withdrawals_test(spec, state, random.Random(200))
|
yield from run_random_full_withdrawals_test(spec, state, random.Random(200))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_random_full_withdrawals_3(spec, state):
|
def test_random_full_withdrawals_3(spec, state):
|
||||||
yield from run_random_full_withdrawals_test(spec, state, random.Random(2000000))
|
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
|
# More partial withdrawal cases
|
||||||
#
|
#
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_no_max_effective_balance(spec, state):
|
def test_success_no_max_effective_balance(spec, state):
|
||||||
validator_index = len(state.validators) // 2
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_no_excess_balance(spec, state):
|
def test_success_no_excess_balance(spec, state):
|
||||||
validator_index = len(state.validators) // 2
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_excess_balance_but_no_max_effective_balance(spec, state):
|
def test_success_excess_balance_but_no_max_effective_balance(spec, state):
|
||||||
validator_index = len(state.validators) // 2
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=0)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_one_partial_withdrawable_not_yet_active(spec, state):
|
def test_success_one_partial_withdrawable_not_yet_active(spec, state):
|
||||||
validator_index = len(state.validators) // 2
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_one_partial_withdrawable_in_exit_queue(spec, state):
|
def test_success_one_partial_withdrawable_in_exit_queue(spec, state):
|
||||||
validator_index = len(state.validators) // 2
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_one_partial_withdrawable_exited(spec, state):
|
def test_success_one_partial_withdrawable_exited(spec, state):
|
||||||
validator_index = len(state.validators) // 2
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_one_partial_withdrawable_active_and_slashed(spec, state):
|
def test_success_one_partial_withdrawable_active_and_slashed(spec, state):
|
||||||
validator_index = len(state.validators) // 2
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_one_partial_withdrawable_exited_and_slashed(spec, state):
|
def test_success_one_partial_withdrawable_exited_and_slashed(spec, state):
|
||||||
validator_index = len(state.validators) // 2
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=1)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_two_partial_withdrawable(spec, state):
|
def test_success_two_partial_withdrawable(spec, state):
|
||||||
set_validator_partially_withdrawable(spec, state, 0)
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload, num_expected_withdrawals=2)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_max_partial_withdrawable(spec, state):
|
def test_success_max_partial_withdrawable(spec, state):
|
||||||
# Sanity check that this test works for this 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)
|
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")
|
@with_presets([MINIMAL], reason="not enough validators with mainnet config")
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_success_max_plus_one_withdrawable(spec, state):
|
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)
|
yield from run_withdrawals_processing(spec, state, execution_payload)
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_random_0(spec, state):
|
def test_random_0(spec, state):
|
||||||
yield from run_random_partial_withdrawals_test(spec, state, random.Random(0))
|
yield from run_random_partial_withdrawals_test(spec, state, random.Random(0))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_random_partial_withdrawals_1(spec, state):
|
def test_random_partial_withdrawals_1(spec, state):
|
||||||
yield from run_random_partial_withdrawals_test(spec, state, random.Random(1))
|
yield from run_random_partial_withdrawals_test(spec, state, random.Random(1))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_random_partial_withdrawals_2(spec, state):
|
def test_random_partial_withdrawals_2(spec, state):
|
||||||
yield from run_random_partial_withdrawals_test(spec, state, random.Random(2))
|
yield from run_random_partial_withdrawals_test(spec, state, random.Random(2))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_random_partial_withdrawals_3(spec, state):
|
def test_random_partial_withdrawals_3(spec, state):
|
||||||
yield from run_random_partial_withdrawals_test(spec, state, random.Random(3))
|
yield from run_random_partial_withdrawals_test(spec, state, random.Random(3))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_random_partial_withdrawals_4(spec, state):
|
def test_random_partial_withdrawals_4(spec, state):
|
||||||
yield from run_random_partial_withdrawals_test(spec, state, random.Random(4))
|
yield from run_random_partial_withdrawals_test(spec, state, random.Random(4))
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_random_partial_withdrawals_5(spec, state):
|
def test_random_partial_withdrawals_5(spec, state):
|
||||||
yield from run_random_partial_withdrawals_test(spec, state, random.Random(5))
|
yield from run_random_partial_withdrawals_test(spec, state, random.Random(5))
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
from random import Random
|
||||||
|
|
||||||
|
from eth2spec.test.context import (
|
||||||
|
with_phases,
|
||||||
|
with_custom_state,
|
||||||
|
with_presets,
|
||||||
|
spec_test, with_state,
|
||||||
|
low_balances, misc_balances, large_validator_set,
|
||||||
|
)
|
||||||
|
from eth2spec.test.utils import with_meta_tags
|
||||||
|
from eth2spec.test.helpers.constants import (
|
||||||
|
BELLATRIX, CAPELLA,
|
||||||
|
MINIMAL,
|
||||||
|
)
|
||||||
|
from eth2spec.test.helpers.capella.fork import (
|
||||||
|
CAPELLA_FORK_TEST_META_TAGS,
|
||||||
|
run_fork_test,
|
||||||
|
)
|
||||||
|
from eth2spec.test.helpers.random import randomize_state
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[BELLATRIX], other_phases=[CAPELLA])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(CAPELLA_FORK_TEST_META_TAGS)
|
||||||
|
def test_capella_fork_random_0(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(1010))
|
||||||
|
yield from run_fork_test(phases[CAPELLA], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[BELLATRIX], other_phases=[CAPELLA])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(CAPELLA_FORK_TEST_META_TAGS)
|
||||||
|
def test_capella_fork_random_1(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(2020))
|
||||||
|
yield from run_fork_test(phases[CAPELLA], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[BELLATRIX], other_phases=[CAPELLA])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(CAPELLA_FORK_TEST_META_TAGS)
|
||||||
|
def test_capella_fork_random_2(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(3030))
|
||||||
|
yield from run_fork_test(phases[CAPELLA], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[BELLATRIX], other_phases=[CAPELLA])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(CAPELLA_FORK_TEST_META_TAGS)
|
||||||
|
def test_capella_fork_random_3(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(4040))
|
||||||
|
yield from run_fork_test(phases[CAPELLA], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[BELLATRIX], other_phases=[CAPELLA])
|
||||||
|
@spec_test
|
||||||
|
@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
|
||||||
|
@with_meta_tags(CAPELLA_FORK_TEST_META_TAGS)
|
||||||
|
def test_capella_fork_random_low_balances(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(5050))
|
||||||
|
yield from run_fork_test(phases[CAPELLA], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[BELLATRIX], other_phases=[CAPELLA])
|
||||||
|
@spec_test
|
||||||
|
@with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
|
||||||
|
@with_meta_tags(CAPELLA_FORK_TEST_META_TAGS)
|
||||||
|
def test_capella_fork_random_misc_balances(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(6060))
|
||||||
|
yield from run_fork_test(phases[CAPELLA], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[BELLATRIX], other_phases=[CAPELLA])
|
||||||
|
@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=large_validator_set, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
|
||||||
|
@with_meta_tags(CAPELLA_FORK_TEST_META_TAGS)
|
||||||
|
def test_capella_fork_random_large_validator_set(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(7070))
|
||||||
|
yield from run_fork_test(phases[CAPELLA], state)
|
|
@ -1,7 +1,7 @@
|
||||||
from eth2spec.test.context import (
|
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 (
|
from eth2spec.test.helpers.state import (
|
||||||
state_transition_and_sign_block,
|
state_transition_and_sign_block,
|
||||||
)
|
)
|
||||||
|
@ -21,9 +21,13 @@ from eth2spec.test.helpers.withdrawals import (
|
||||||
from eth2spec.test.helpers.voluntary_exits import prepare_signed_exits
|
from eth2spec.test.helpers.voluntary_exits import prepare_signed_exits
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
#
|
||||||
|
# BLSToExecutionChange
|
||||||
|
#
|
||||||
|
|
||||||
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_successful_bls_change(spec, state):
|
def test_success_bls_change(spec, state):
|
||||||
index = 0
|
index = 0
|
||||||
signed_address_change = get_signed_address_change(spec, state, validator_index=index)
|
signed_address_change = get_signed_address_change(spec, state, validator_index=index)
|
||||||
pre_credentials = state.validators[index].withdrawal_credentials
|
pre_credentials = state.validators[index].withdrawal_credentials
|
||||||
|
@ -44,77 +48,9 @@ def test_successful_bls_change(spec, state):
|
||||||
assert post_credentials[12:] == signed_address_change.message.to_execution_address
|
assert post_credentials[12:] == signed_address_change.message.to_execution_address
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_full_withdrawal_in_epoch_transition(spec, state):
|
def test_success_exit_and_bls_change(spec, state):
|
||||||
index = 0
|
|
||||||
current_epoch = spec.get_current_epoch(state)
|
|
||||||
set_validator_fully_withdrawable(spec, state, index, current_epoch)
|
|
||||||
assert len(spec.get_expected_withdrawals(state)) == 1
|
|
||||||
|
|
||||||
yield 'pre', state
|
|
||||||
|
|
||||||
# trigger epoch transition
|
|
||||||
block = build_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
|
|
||||||
signed_block = state_transition_and_sign_block(spec, state, block)
|
|
||||||
|
|
||||||
yield 'blocks', [signed_block]
|
|
||||||
yield 'post', state
|
|
||||||
|
|
||||||
assert state.balances[index] == 0
|
|
||||||
assert len(spec.get_expected_withdrawals(state)) == 0
|
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
|
||||||
@spec_state_test
|
|
||||||
def test_partial_withdrawal_in_epoch_transition(spec, state):
|
|
||||||
index = state.next_withdrawal_index
|
|
||||||
set_validator_partially_withdrawable(spec, state, index, excess_balance=1000000000000)
|
|
||||||
pre_balance = state.balances[index]
|
|
||||||
|
|
||||||
assert len(spec.get_expected_withdrawals(state)) == 1
|
|
||||||
|
|
||||||
yield 'pre', state
|
|
||||||
|
|
||||||
# trigger epoch transition
|
|
||||||
block = build_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
|
|
||||||
signed_block = state_transition_and_sign_block(spec, state, block)
|
|
||||||
|
|
||||||
yield 'blocks', [signed_block]
|
|
||||||
yield 'post', state
|
|
||||||
|
|
||||||
assert state.balances[index] < pre_balance
|
|
||||||
# Potentially less than due to sync committee penalty
|
|
||||||
assert state.balances[index] <= spec.MAX_EFFECTIVE_BALANCE
|
|
||||||
assert len(spec.get_expected_withdrawals(state)) == 0
|
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
|
||||||
@spec_state_test
|
|
||||||
def test_many_partial_withdrawals_in_epoch_transition(spec, state):
|
|
||||||
assert len(state.validators) > spec.MAX_WITHDRAWALS_PER_PAYLOAD
|
|
||||||
|
|
||||||
for i in range(spec.MAX_WITHDRAWALS_PER_PAYLOAD + 1):
|
|
||||||
index = (i + state.next_withdrawal_index) % len(state.validators)
|
|
||||||
set_validator_partially_withdrawable(spec, state, index, excess_balance=1000000000000)
|
|
||||||
|
|
||||||
assert len(spec.get_expected_withdrawals(state)) == spec.MAX_WITHDRAWALS_PER_PAYLOAD
|
|
||||||
|
|
||||||
yield 'pre', state
|
|
||||||
|
|
||||||
# trigger epoch transition
|
|
||||||
block = build_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
|
|
||||||
signed_block = state_transition_and_sign_block(spec, state, block)
|
|
||||||
|
|
||||||
yield 'blocks', [signed_block]
|
|
||||||
yield 'post', state
|
|
||||||
|
|
||||||
assert len(spec.get_expected_withdrawals(state)) == 1
|
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
|
||||||
@spec_state_test
|
|
||||||
def test_exit_and_bls_change(spec, state):
|
|
||||||
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
|
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
|
||||||
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
|
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
|
||||||
|
|
||||||
|
@ -141,6 +77,121 @@ def test_exit_and_bls_change(spec, state):
|
||||||
assert spec.is_fully_withdrawable_validator(validator, balance, validator.withdrawable_epoch)
|
assert spec.is_fully_withdrawable_validator(validator, balance, validator.withdrawable_epoch)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases([CAPELLA])
|
||||||
|
@spec_state_test
|
||||||
|
def test_invalid_duplicate_bls_changes_same_block(spec, state):
|
||||||
|
index = 0
|
||||||
|
signed_address_change = get_signed_address_change(spec, state, validator_index=index)
|
||||||
|
yield 'pre', state
|
||||||
|
|
||||||
|
block = build_empty_block_for_next_slot(spec, state)
|
||||||
|
|
||||||
|
# Double BLSToExecutionChange of the same validator
|
||||||
|
for _ in range(2):
|
||||||
|
block.body.bls_to_execution_changes.append(signed_address_change)
|
||||||
|
|
||||||
|
signed_block = state_transition_and_sign_block(spec, state, block, expect_fail=True)
|
||||||
|
|
||||||
|
yield 'blocks', [signed_block]
|
||||||
|
yield 'post', None
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases([CAPELLA])
|
||||||
|
@spec_state_test
|
||||||
|
def test_invalid_two_bls_changes_of_different_addresses_same_validator_same_block(spec, state):
|
||||||
|
index = 0
|
||||||
|
|
||||||
|
signed_address_change_1 = get_signed_address_change(spec, state, validator_index=index,
|
||||||
|
to_execution_address=b'\x12' * 20)
|
||||||
|
signed_address_change_2 = get_signed_address_change(spec, state, validator_index=index,
|
||||||
|
to_execution_address=b'\x34' * 20)
|
||||||
|
assert signed_address_change_1 != signed_address_change_2
|
||||||
|
|
||||||
|
yield 'pre', state
|
||||||
|
|
||||||
|
block = build_empty_block_for_next_slot(spec, state)
|
||||||
|
|
||||||
|
block.body.bls_to_execution_changes.append(signed_address_change_1)
|
||||||
|
block.body.bls_to_execution_changes.append(signed_address_change_2)
|
||||||
|
|
||||||
|
signed_block = state_transition_and_sign_block(spec, state, block, expect_fail=True)
|
||||||
|
|
||||||
|
yield 'blocks', [signed_block]
|
||||||
|
yield 'post', None
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Withdrawals
|
||||||
|
#
|
||||||
|
|
||||||
|
@with_phases([CAPELLA])
|
||||||
|
@spec_state_test
|
||||||
|
def test_full_withdrawal_in_epoch_transition(spec, state):
|
||||||
|
index = 0
|
||||||
|
current_epoch = spec.get_current_epoch(state)
|
||||||
|
set_validator_fully_withdrawable(spec, state, index, current_epoch)
|
||||||
|
assert len(spec.get_expected_withdrawals(state)) == 1
|
||||||
|
|
||||||
|
yield 'pre', state
|
||||||
|
|
||||||
|
# trigger epoch transition
|
||||||
|
block = build_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
|
||||||
|
signed_block = state_transition_and_sign_block(spec, state, block)
|
||||||
|
|
||||||
|
yield 'blocks', [signed_block]
|
||||||
|
yield 'post', state
|
||||||
|
|
||||||
|
assert state.balances[index] == 0
|
||||||
|
assert len(spec.get_expected_withdrawals(state)) == 0
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases([CAPELLA])
|
||||||
|
@spec_state_test
|
||||||
|
def test_partial_withdrawal_in_epoch_transition(spec, state):
|
||||||
|
index = state.next_withdrawal_index
|
||||||
|
set_validator_partially_withdrawable(spec, state, index, excess_balance=1000000000000)
|
||||||
|
pre_balance = state.balances[index]
|
||||||
|
|
||||||
|
assert len(spec.get_expected_withdrawals(state)) == 1
|
||||||
|
|
||||||
|
yield 'pre', state
|
||||||
|
|
||||||
|
# trigger epoch transition
|
||||||
|
block = build_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
|
||||||
|
signed_block = state_transition_and_sign_block(spec, state, block)
|
||||||
|
|
||||||
|
yield 'blocks', [signed_block]
|
||||||
|
yield 'post', state
|
||||||
|
|
||||||
|
assert state.balances[index] < pre_balance
|
||||||
|
# Potentially less than due to sync committee penalty
|
||||||
|
assert state.balances[index] <= spec.MAX_EFFECTIVE_BALANCE
|
||||||
|
assert len(spec.get_expected_withdrawals(state)) == 0
|
||||||
|
|
||||||
|
|
||||||
|
@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
|
||||||
|
|
||||||
|
for i in range(spec.MAX_WITHDRAWALS_PER_PAYLOAD + 1):
|
||||||
|
index = (i + state.next_withdrawal_index) % len(state.validators)
|
||||||
|
set_validator_partially_withdrawable(spec, state, index, excess_balance=1000000000000)
|
||||||
|
|
||||||
|
assert len(spec.get_expected_withdrawals(state)) == spec.MAX_WITHDRAWALS_PER_PAYLOAD
|
||||||
|
|
||||||
|
yield 'pre', state
|
||||||
|
|
||||||
|
# trigger epoch transition
|
||||||
|
block = build_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
|
||||||
|
signed_block = state_transition_and_sign_block(spec, state, block)
|
||||||
|
|
||||||
|
yield 'blocks', [signed_block]
|
||||||
|
yield 'post', state
|
||||||
|
|
||||||
|
assert len(spec.get_expected_withdrawals(state)) == 1
|
||||||
|
|
||||||
|
|
||||||
def _perform_valid_withdrawal(spec, state):
|
def _perform_valid_withdrawal(spec, state):
|
||||||
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
|
fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals(
|
||||||
spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4,
|
spec, state, num_partial_withdrawals=spec.MAX_WITHDRAWALS_PER_PAYLOAD * 4,
|
||||||
|
@ -170,7 +221,7 @@ def _perform_valid_withdrawal(spec, state):
|
||||||
return pre_state, signed_block_1, pre_next_withdrawal_index
|
return pre_state, signed_block_1, pre_next_withdrawal_index
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_withdrawal_success_two_blocks(spec, state):
|
def test_withdrawal_success_two_blocks(spec, state):
|
||||||
pre_state, signed_block_1, pre_next_withdrawal_index = _perform_valid_withdrawal(spec, state)
|
pre_state, signed_block_1, pre_next_withdrawal_index = _perform_valid_withdrawal(spec, state)
|
||||||
|
@ -187,7 +238,7 @@ def test_withdrawal_success_two_blocks(spec, state):
|
||||||
yield 'post', state
|
yield 'post', state
|
||||||
|
|
||||||
|
|
||||||
@with_capella_and_later
|
@with_phases([CAPELLA])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_withdrawal_fail_second_block_payload_isnt_compatible(spec, state):
|
def test_withdrawal_fail_second_block_payload_isnt_compatible(spec, state):
|
||||||
_perform_valid_withdrawal(spec, state)
|
_perform_valid_withdrawal(spec, state)
|
||||||
|
|
|
@ -600,6 +600,13 @@ def only_generator(reason):
|
||||||
return _decorator
|
return _decorator
|
||||||
|
|
||||||
|
|
||||||
|
def with_test_suite_name(suite_name: str):
|
||||||
|
def _decorator(inner):
|
||||||
|
inner.suite_name = suite_name
|
||||||
|
return inner
|
||||||
|
return _decorator
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Fork transition state tests
|
# Fork transition state tests
|
||||||
#
|
#
|
||||||
|
|
|
@ -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)
|
|
@ -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)
|
|
@ -0,0 +1,82 @@
|
||||||
|
from eth2spec.test.context import (
|
||||||
|
with_phases,
|
||||||
|
with_custom_state,
|
||||||
|
with_presets,
|
||||||
|
spec_test, with_state,
|
||||||
|
low_balances, misc_balances, large_validator_set,
|
||||||
|
)
|
||||||
|
from eth2spec.test.utils import with_meta_tags
|
||||||
|
from eth2spec.test.helpers.constants import (
|
||||||
|
CAPELLA, EIP4844,
|
||||||
|
MINIMAL,
|
||||||
|
)
|
||||||
|
from eth2spec.test.helpers.state import (
|
||||||
|
next_epoch,
|
||||||
|
next_epoch_via_block,
|
||||||
|
)
|
||||||
|
from eth2spec.test.helpers.eip4844.fork import (
|
||||||
|
EIP4844_FORK_TEST_META_TAGS,
|
||||||
|
run_fork_test,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_fork_base_state(spec, phases, state):
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_fork_next_epoch(spec, phases, state):
|
||||||
|
next_epoch(spec, state)
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_fork_next_epoch_with_block(spec, phases, state):
|
||||||
|
next_epoch_via_block(spec, state)
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_fork_many_next_epoch(spec, phases, state):
|
||||||
|
for _ in range(3):
|
||||||
|
next_epoch(spec, state)
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
|
||||||
|
@spec_test
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_fork_random_low_balances(spec, phases, state):
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
|
||||||
|
@spec_test
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_fork_random_misc_balances(spec, phases, state):
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@with_presets([MINIMAL],
|
||||||
|
reason="mainnet config leads to larger validator set than limit of public/private keys pre-generated")
|
||||||
|
@with_custom_state(balances_fn=large_validator_set, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
|
||||||
|
@spec_test
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_fork_random_large_validator_set(spec, phases, state):
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
|
@ -0,0 +1,84 @@
|
||||||
|
from random import Random
|
||||||
|
|
||||||
|
from eth2spec.test.context import (
|
||||||
|
with_phases,
|
||||||
|
with_custom_state,
|
||||||
|
with_presets,
|
||||||
|
spec_test, with_state,
|
||||||
|
low_balances, misc_balances, large_validator_set,
|
||||||
|
)
|
||||||
|
from eth2spec.test.utils import with_meta_tags
|
||||||
|
from eth2spec.test.helpers.constants import (
|
||||||
|
CAPELLA, EIP4844,
|
||||||
|
MINIMAL,
|
||||||
|
)
|
||||||
|
from eth2spec.test.helpers.eip4844.fork import (
|
||||||
|
EIP4844_FORK_TEST_META_TAGS,
|
||||||
|
run_fork_test,
|
||||||
|
)
|
||||||
|
from eth2spec.test.helpers.random import randomize_state
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_eip4844_fork_random_0(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(1010))
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_eip4844_fork_random_1(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(2020))
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_eip4844_fork_random_2(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(3030))
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@spec_test
|
||||||
|
@with_state
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_eip4844_fork_random_3(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(4040))
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@spec_test
|
||||||
|
@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_eip4844_fork_random_low_balances(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(5050))
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@spec_test
|
||||||
|
@with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_eip4844_fork_random_misc_balances(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(6060))
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(phases=[CAPELLA], other_phases=[EIP4844])
|
||||||
|
@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=large_validator_set, threshold_fn=lambda spec: spec.config.EJECTION_BALANCE)
|
||||||
|
@with_meta_tags(EIP4844_FORK_TEST_META_TAGS)
|
||||||
|
def test_eip4844_fork_random_large_validator_set(spec, phases, state):
|
||||||
|
randomize_state(spec, state, rng=Random(7070))
|
||||||
|
yield from run_fork_test(phases[EIP4844], state)
|
|
@ -0,0 +1,438 @@
|
||||||
|
"""
|
||||||
|
This module is generated from the ``random`` test generator.
|
||||||
|
Please do not edit this file manually.
|
||||||
|
See the README for that generator for more information.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from eth2spec.test.helpers.constants import EIP4844
|
||||||
|
from eth2spec.test.context import (
|
||||||
|
misc_balances_in_default_range_with_many_validators,
|
||||||
|
with_phases,
|
||||||
|
zero_activation_threshold,
|
||||||
|
only_generator,
|
||||||
|
)
|
||||||
|
from eth2spec.test.context import (
|
||||||
|
always_bls,
|
||||||
|
spec_test,
|
||||||
|
with_custom_state,
|
||||||
|
single_phase,
|
||||||
|
)
|
||||||
|
from eth2spec.test.utils.randomized_block_tests import (
|
||||||
|
run_generated_randomized_test,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_0(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:random_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'validation': 'validate_is_not_leaking', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 0, 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'random_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_1(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:random_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'validation': 'validate_is_not_leaking', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'random_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 0, 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_2(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:penultimate_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:last_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'validation': 'validate_is_not_leaking', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'penultimate_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'last_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_3(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:last_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:last_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'validation': 'validate_is_not_leaking', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'last_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'last_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_4(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:last_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:penultimate_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'validation': 'validate_is_not_leaking', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'last_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'penultimate_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_5(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:random_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:random_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'validation': 'validate_is_not_leaking', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'random_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'random_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_6(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:penultimate_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:penultimate_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'validation': 'validate_is_not_leaking', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'penultimate_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'penultimate_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_7(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'validation': 'validate_is_not_leaking', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 0, 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 0, 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_8(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:epochs_until_leak,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:random_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'epochs_to_skip': 'epochs_until_leak', 'validation': 'validate_is_leaking', 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 0, 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'random_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_9(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:epochs_until_leak,slots:0,with-block:no_block
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:random_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'epochs_to_skip': 'epochs_until_leak', 'validation': 'validate_is_leaking', 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'random_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 0, 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_10(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:epochs_until_leak,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:penultimate_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:last_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'epochs_to_skip': 'epochs_until_leak', 'validation': 'validate_is_leaking', 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'penultimate_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'last_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_11(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:epochs_until_leak,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:last_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:last_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'epochs_to_skip': 'epochs_until_leak', 'validation': 'validate_is_leaking', 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'last_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'last_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_12(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:epochs_until_leak,slots:0,with-block:no_block
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:last_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:penultimate_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'epochs_to_skip': 'epochs_until_leak', 'validation': 'validate_is_leaking', 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'last_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'penultimate_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_13(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:epochs_until_leak,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:random_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:random_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'epochs_to_skip': 'epochs_until_leak', 'validation': 'validate_is_leaking', 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'random_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'random_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_14(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:epochs_until_leak,slots:0,with-block:no_block
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:penultimate_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:penultimate_slot_in_epoch,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'epochs_to_skip': 'epochs_until_leak', 'validation': 'validate_is_leaking', 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'penultimate_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 0, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 'penultimate_slot_in_epoch', 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_generator("randomized test for broad coverage, not point-to-point CI")
|
||||||
|
@with_phases([EIP4844])
|
||||||
|
@with_custom_state(
|
||||||
|
balances_fn=misc_balances_in_default_range_with_many_validators,
|
||||||
|
threshold_fn=zero_activation_threshold
|
||||||
|
)
|
||||||
|
@spec_test
|
||||||
|
@single_phase
|
||||||
|
@always_bls
|
||||||
|
def test_randomized_15(spec, state):
|
||||||
|
# scenario as high-level, informal text:
|
||||||
|
# epochs:epochs_until_leak,slots:0,with-block:no_block
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
# epochs:1,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:no_block
|
||||||
|
# epochs:0,slots:0,with-block:random_block_eip4844
|
||||||
|
scenario = {'transitions': [{'epochs_to_skip': 'epochs_until_leak', 'validation': 'validate_is_leaking', 'slots_to_skip': 0, 'block_producer': 'no_block'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 0, 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}, {'epochs_to_skip': 1, 'slots_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'slots_to_skip': 0, 'epochs_to_skip': 0, 'block_producer': 'no_block', 'validation': 'no_op_validation'}, {'block_producer': 'random_block_eip4844', 'epochs_to_skip': 0, 'slots_to_skip': 0, 'validation': 'no_op_validation'}], 'state_randomizer': 'randomize_state_eip4844'} # noqa: E501
|
||||||
|
yield from run_generated_randomized_test(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
scenario,
|
||||||
|
)
|
|
@ -17,4 +17,4 @@ def test_verify_kzg_proof(spec, state):
|
||||||
proof = spec.compute_kzg_proof(polynomial, x)
|
proof = spec.compute_kzg_proof(polynomial, x)
|
||||||
|
|
||||||
y = spec.evaluate_polynomial_in_evaluation_form(polynomial, x)
|
y = spec.evaluate_polynomial_in_evaluation_form(polynomial, x)
|
||||||
assert spec.verify_kzg_proof(commitment, x, y, proof)
|
assert spec.verify_kzg_proof_impl(commitment, x, y, proof)
|
||||||
|
|
|
@ -2,7 +2,7 @@ from eth2spec.utils import bls
|
||||||
from eth2spec.test.helpers.keys import pubkeys, privkeys, pubkey_to_privkey
|
from eth2spec.test.helpers.keys import pubkeys, privkeys, pubkey_to_privkey
|
||||||
|
|
||||||
|
|
||||||
def get_signed_address_change(spec, state, validator_index=None, withdrawal_pubkey=None):
|
def get_signed_address_change(spec, state, validator_index=None, withdrawal_pubkey=None, to_execution_address=None):
|
||||||
if validator_index is None:
|
if validator_index is None:
|
||||||
validator_index = 0
|
validator_index = 0
|
||||||
|
|
||||||
|
@ -13,11 +13,14 @@ def get_signed_address_change(spec, state, validator_index=None, withdrawal_pubk
|
||||||
else:
|
else:
|
||||||
withdrawal_privkey = pubkey_to_privkey[withdrawal_pubkey]
|
withdrawal_privkey = pubkey_to_privkey[withdrawal_pubkey]
|
||||||
|
|
||||||
|
if to_execution_address is None:
|
||||||
|
to_execution_address = b'\x42' * 20
|
||||||
|
|
||||||
domain = spec.get_domain(state, spec.DOMAIN_BLS_TO_EXECUTION_CHANGE)
|
domain = spec.get_domain(state, spec.DOMAIN_BLS_TO_EXECUTION_CHANGE)
|
||||||
address_change = spec.BLSToExecutionChange(
|
address_change = spec.BLSToExecutionChange(
|
||||||
validator_index=validator_index,
|
validator_index=validator_index,
|
||||||
from_bls_pubkey=withdrawal_pubkey,
|
from_bls_pubkey=withdrawal_pubkey,
|
||||||
to_execution_address=b'\x42' * 20,
|
to_execution_address=to_execution_address,
|
||||||
)
|
)
|
||||||
|
|
||||||
signing_root = spec.compute_signing_root(address_change, domain)
|
signing_root = spec.compute_signing_root(address_change, domain)
|
||||||
|
|
|
@ -32,6 +32,7 @@ ALL_FORK_UPGRADES = {
|
||||||
PHASE0: ALTAIR,
|
PHASE0: ALTAIR,
|
||||||
ALTAIR: BELLATRIX,
|
ALTAIR: BELLATRIX,
|
||||||
BELLATRIX: CAPELLA,
|
BELLATRIX: CAPELLA,
|
||||||
|
CAPELLA: EIP4844,
|
||||||
}
|
}
|
||||||
ALL_PRE_POST_FORKS = ALL_FORK_UPGRADES.items()
|
ALL_PRE_POST_FORKS = ALL_FORK_UPGRADES.items()
|
||||||
AFTER_BELLATRIX_UPGRADES = {key: value for key, value in ALL_FORK_UPGRADES.items() if key != PHASE0}
|
AFTER_BELLATRIX_UPGRADES = {key: value for key, value in ALL_FORK_UPGRADES.items() if key != PHASE0}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
from eth2spec.test.helpers.constants import (
|
||||||
|
EIP4844,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
EIP4844_FORK_TEST_META_TAGS = {
|
||||||
|
'fork': EIP4844,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def run_fork_test(post_spec, pre_state):
|
||||||
|
yield 'pre', pre_state
|
||||||
|
|
||||||
|
post_state = post_spec.upgrade_to_eip4844(pre_state)
|
||||||
|
|
||||||
|
# Stable fields
|
||||||
|
stable_fields = [
|
||||||
|
'genesis_time', 'genesis_validators_root', 'slot',
|
||||||
|
# History
|
||||||
|
'latest_block_header', 'block_roots', 'state_roots', 'historical_roots',
|
||||||
|
# Eth1
|
||||||
|
'eth1_data', 'eth1_data_votes', 'eth1_deposit_index',
|
||||||
|
# Registry
|
||||||
|
'validators', 'balances',
|
||||||
|
# Randomness
|
||||||
|
'randao_mixes',
|
||||||
|
# Slashings
|
||||||
|
'slashings',
|
||||||
|
# Participation
|
||||||
|
'previous_epoch_participation', 'current_epoch_participation',
|
||||||
|
# Finality
|
||||||
|
'justification_bits', 'previous_justified_checkpoint', 'current_justified_checkpoint', 'finalized_checkpoint',
|
||||||
|
# Inactivity
|
||||||
|
'inactivity_scores',
|
||||||
|
# Sync
|
||||||
|
'current_sync_committee', 'next_sync_committee',
|
||||||
|
# Withdrawals
|
||||||
|
'next_withdrawal_index', 'next_withdrawal_validator_index',
|
||||||
|
]
|
||||||
|
for field in stable_fields:
|
||||||
|
assert getattr(pre_state, field) == getattr(post_state, field)
|
||||||
|
|
||||||
|
# Modified fields
|
||||||
|
modified_fields = ['fork', 'latest_execution_payload_header']
|
||||||
|
for field in modified_fields:
|
||||||
|
assert getattr(pre_state, field) != getattr(post_state, field)
|
||||||
|
|
||||||
|
assert len(pre_state.validators) == len(post_state.validators)
|
||||||
|
for pre_validator, post_validator in zip(pre_state.validators, post_state.validators):
|
||||||
|
stable_validator_fields = [
|
||||||
|
'pubkey', 'withdrawal_credentials',
|
||||||
|
'effective_balance',
|
||||||
|
'slashed',
|
||||||
|
'activation_eligibility_epoch', 'activation_epoch', 'exit_epoch', 'withdrawable_epoch',
|
||||||
|
]
|
||||||
|
for field in stable_validator_fields:
|
||||||
|
assert getattr(pre_validator, field) == getattr(post_validator, field)
|
||||||
|
|
||||||
|
assert pre_state.fork.current_version == post_state.fork.previous_version
|
||||||
|
assert post_state.fork.current_version == post_spec.config.EIP4844_FORK_VERSION
|
||||||
|
assert post_state.fork.epoch == post_spec.get_current_epoch(post_state)
|
||||||
|
|
||||||
|
yield 'post', post_state
|
|
@ -5,7 +5,7 @@ from .constants import (
|
||||||
|
|
||||||
def is_post_fork(a, b):
|
def is_post_fork(a, b):
|
||||||
if a == EIP4844:
|
if a == EIP4844:
|
||||||
return b in [PHASE0, ALTAIR, BELLATRIX, EIP4844]
|
return b in [PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844]
|
||||||
if a == CAPELLA:
|
if a == CAPELLA:
|
||||||
return b in [PHASE0, ALTAIR, BELLATRIX, CAPELLA]
|
return b in [PHASE0, ALTAIR, BELLATRIX, CAPELLA]
|
||||||
if a == BELLATRIX:
|
if a == BELLATRIX:
|
||||||
|
|
|
@ -433,7 +433,7 @@ def test_proposer_slashing(spec, state):
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_double_same_proposer_slashings_same_block(spec, state):
|
def test_invalid_duplicate_proposer_slashings_same_block(spec, state):
|
||||||
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
|
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
|
||||||
slashed_index = proposer_slashing.signed_header_1.message.proposer_index
|
slashed_index = proposer_slashing.signed_header_1.message.proposer_index
|
||||||
assert not state.validators[slashed_index].slashed
|
assert not state.validators[slashed_index].slashed
|
||||||
|
@ -450,7 +450,7 @@ def test_double_same_proposer_slashings_same_block(spec, state):
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_double_similar_proposer_slashings_same_block(spec, state):
|
def test_invalid_similar_proposer_slashings_same_block(spec, state):
|
||||||
slashed_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
slashed_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||||
|
|
||||||
# Same validator, but different slashable offences in the same block
|
# Same validator, but different slashable offences in the same block
|
||||||
|
@ -549,7 +549,7 @@ def test_attester_slashing(spec, state):
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_duplicate_attester_slashing(spec, state):
|
def test_invalid_duplicate_attester_slashing_same_block(spec, state):
|
||||||
if spec.MAX_ATTESTER_SLASHINGS < 2:
|
if spec.MAX_ATTESTER_SLASHINGS < 2:
|
||||||
return dump_skipping_message("Skip test if config cannot handle multiple AttesterSlashings per block")
|
return dump_skipping_message("Skip test if config cannot handle multiple AttesterSlashings per block")
|
||||||
|
|
||||||
|
@ -744,6 +744,27 @@ def test_deposit_in_block(spec, state):
|
||||||
assert state.validators[validator_index].pubkey == pubkeys[validator_index]
|
assert state.validators[validator_index].pubkey == pubkeys[validator_index]
|
||||||
|
|
||||||
|
|
||||||
|
@with_all_phases
|
||||||
|
@spec_state_test
|
||||||
|
def test_invalid_duplicate_deposit_same_block(spec, state):
|
||||||
|
validator_index = len(state.validators)
|
||||||
|
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||||
|
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
|
||||||
|
|
||||||
|
yield 'pre', state
|
||||||
|
|
||||||
|
block = build_empty_block_for_next_slot(spec, state)
|
||||||
|
|
||||||
|
# The same deposit of the same validator
|
||||||
|
for _ in range(2):
|
||||||
|
block.body.deposits.append(deposit)
|
||||||
|
|
||||||
|
signed_block = state_transition_and_sign_block(spec, state, block, expect_fail=True)
|
||||||
|
|
||||||
|
yield 'blocks', [signed_block]
|
||||||
|
yield 'post', None
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_deposit_top_up(spec, state):
|
def test_deposit_top_up(spec, state):
|
||||||
|
@ -831,6 +852,49 @@ def test_attestation(spec, state):
|
||||||
assert spec.hash_tree_root(state.previous_epoch_participation) == pre_current_epoch_participation_root
|
assert spec.hash_tree_root(state.previous_epoch_participation) == pre_current_epoch_participation_root
|
||||||
|
|
||||||
|
|
||||||
|
@with_all_phases
|
||||||
|
@spec_state_test
|
||||||
|
def test_duplicate_attestation_same_block(spec, state):
|
||||||
|
next_epoch(spec, state)
|
||||||
|
|
||||||
|
yield 'pre', state
|
||||||
|
|
||||||
|
attestation_block = build_empty_block(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
|
||||||
|
attestation = get_valid_attestation(spec, state, index=index, signed=True)
|
||||||
|
|
||||||
|
if not is_post_altair(spec):
|
||||||
|
pre_current_attestations_len = len(state.current_epoch_attestations)
|
||||||
|
|
||||||
|
# Add to state via block transition
|
||||||
|
for _ in range(2):
|
||||||
|
attestation_block.body.attestations.append(attestation)
|
||||||
|
signed_attestation_block = state_transition_and_sign_block(spec, state, attestation_block)
|
||||||
|
|
||||||
|
if not is_post_altair(spec):
|
||||||
|
assert len(state.current_epoch_attestations) == pre_current_attestations_len + 2
|
||||||
|
# Epoch transition should move to previous_epoch_attestations
|
||||||
|
pre_current_attestations_root = spec.hash_tree_root(state.current_epoch_attestations)
|
||||||
|
else:
|
||||||
|
pre_current_epoch_participation_root = spec.hash_tree_root(state.current_epoch_participation)
|
||||||
|
|
||||||
|
epoch_block = build_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
|
||||||
|
signed_epoch_block = state_transition_and_sign_block(spec, state, epoch_block)
|
||||||
|
|
||||||
|
yield 'blocks', [signed_attestation_block, signed_epoch_block]
|
||||||
|
yield 'post', state
|
||||||
|
|
||||||
|
if not is_post_altair(spec):
|
||||||
|
assert len(state.current_epoch_attestations) == 0
|
||||||
|
assert spec.hash_tree_root(state.previous_epoch_attestations) == pre_current_attestations_root
|
||||||
|
else:
|
||||||
|
for index in range(len(state.validators)):
|
||||||
|
assert state.current_epoch_participation[index] == spec.ParticipationFlags(0b0000_0000)
|
||||||
|
assert spec.hash_tree_root(state.previous_epoch_participation) == pre_current_epoch_participation_root
|
||||||
|
|
||||||
|
|
||||||
# After SHARDING is enabled, a committee is computed for SHARD_COMMITTEE_PERIOD slots ago,
|
# After SHARDING is enabled, a committee is computed for SHARD_COMMITTEE_PERIOD slots ago,
|
||||||
# exceeding the minimal-config randao mixes memory size.
|
# exceeding the minimal-config randao mixes memory size.
|
||||||
# Applies to all voluntary-exit sanity block tests.
|
# Applies to all voluntary-exit sanity block tests.
|
||||||
|
@ -866,7 +930,7 @@ def test_voluntary_exit(spec, state):
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_double_validator_exit_same_block(spec, state):
|
def test_invalid_duplicate_validator_exit_same_block(spec, state):
|
||||||
validator_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
validator_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||||
|
|
||||||
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
|
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
|
||||||
|
|
|
@ -20,6 +20,9 @@ from eth2spec.test.helpers.random import (
|
||||||
randomize_state as randomize_state_helper,
|
randomize_state as randomize_state_helper,
|
||||||
patch_state_to_non_leaking,
|
patch_state_to_non_leaking,
|
||||||
)
|
)
|
||||||
|
from eth2spec.test.helpers.sharding import (
|
||||||
|
get_sample_opaque_tx,
|
||||||
|
)
|
||||||
from eth2spec.test.helpers.state import (
|
from eth2spec.test.helpers.state import (
|
||||||
next_slot,
|
next_slot,
|
||||||
next_epoch,
|
next_epoch,
|
||||||
|
@ -78,6 +81,17 @@ def randomize_state_capella(spec, state, stats, exit_fraction=0.1, slash_fractio
|
||||||
stats,
|
stats,
|
||||||
exit_fraction=exit_fraction,
|
exit_fraction=exit_fraction,
|
||||||
slash_fraction=slash_fraction)
|
slash_fraction=slash_fraction)
|
||||||
|
# TODO: randomize withdrawals
|
||||||
|
return scenario_state
|
||||||
|
|
||||||
|
|
||||||
|
def randomize_state_eip4844(spec, state, stats, exit_fraction=0.1, slash_fraction=0.1):
|
||||||
|
scenario_state = randomize_state_capella(spec,
|
||||||
|
state,
|
||||||
|
stats,
|
||||||
|
exit_fraction=exit_fraction,
|
||||||
|
slash_fraction=slash_fraction)
|
||||||
|
# TODO: randomize execution payload
|
||||||
return scenario_state
|
return scenario_state
|
||||||
|
|
||||||
|
|
||||||
|
@ -215,6 +229,16 @@ def random_block_capella(spec, state, signed_blocks, scenario_state, rng=Random(
|
||||||
return block
|
return block
|
||||||
|
|
||||||
|
|
||||||
|
def random_block_eip4844(spec, state, signed_blocks, scenario_state, rng=Random(3456)):
|
||||||
|
block = random_block_capella(spec, state, signed_blocks, scenario_state)
|
||||||
|
# TODO: more commitments. blob_kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK]
|
||||||
|
opaque_tx, _, blob_kzg_commitments = get_sample_opaque_tx(spec, blob_count=1)
|
||||||
|
block.body.execution_payload.transactions = [opaque_tx]
|
||||||
|
block.body.blob_kzg_commitments = blob_kzg_commitments
|
||||||
|
|
||||||
|
return block
|
||||||
|
|
||||||
|
|
||||||
# validations
|
# validations
|
||||||
|
|
||||||
def no_op_validation(_spec, _state):
|
def no_op_validation(_spec, _state):
|
||||||
|
|
|
@ -5,24 +5,26 @@ generation and verification of merkle proofs based on static data.
|
||||||
|
|
||||||
## Test case format
|
## Test case format
|
||||||
|
|
||||||
### `state.ssz_snappy`
|
Tests for each individual SSZ type are grouped into a `suite` indicating the SSZ type name.
|
||||||
|
|
||||||
An SSZ-snappy encoded `BeaconState` object from which other data is generated.
|
### `object.yaml`
|
||||||
|
|
||||||
|
A SSZ-snappy encoded object from which other data is generated. The SSZ type can be determined from the test `suite` name.
|
||||||
|
|
||||||
### `proof.yaml`
|
### `proof.yaml`
|
||||||
|
|
||||||
A proof of the leaf value (a merkle root) at generalized-index `leaf_index` in the given `state`.
|
A proof of the leaf value (a merkle root) at generalized-index `leaf_index` in the given `object`.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
leaf: Bytes32 # string, hex encoded, with 0x prefix
|
leaf: Bytes32 # string, hex encoded, with 0x prefix
|
||||||
leaf_index: int # integer, decimal
|
leaf_index: int # integer, decimal
|
||||||
branch: list of Bytes32 # list, each element is a string, hex encoded, with 0x prefix
|
branch: list of Bytes32 # list, each element is a string, hex encoded, with 0x prefix
|
||||||
```
|
```
|
||||||
|
|
||||||
## Condition
|
## Condition
|
||||||
|
|
||||||
A test-runner can implement the following assertions:
|
A test-runner can implement the following assertions:
|
||||||
- Check that `is_valid_merkle_branch` confirms `leaf` at `leaf_index` to verify
|
- Check that `is_valid_merkle_branch` confirms `leaf` at `leaf_index` to verify
|
||||||
against `has_tree_root(state)` and `proof`.
|
against `hash_tree_root(object)` and `branch`.
|
||||||
- If the implementation supports generating merkle proofs, check that the
|
- If the implementation supports generating merkle proofs, check that the
|
||||||
self-generated proof matches the `proof` provided with the test.
|
self-generated proof matches the `branch` provided with the test.
|
||||||
|
|
|
@ -186,7 +186,7 @@ if __name__ == "__main__":
|
||||||
ALTAIR: altair_mods,
|
ALTAIR: altair_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="sanity", specs=specs, all_mods=all_mods)
|
run_state_test_generators(runner_name="sanity", all_mods=all_mods)
|
||||||
```
|
```
|
||||||
|
|
||||||
Here multiple phases load the configuration, and the stream of test cases is derived from a pytest file using the `eth2spec.gen_helpers.gen_from_tests.gen.run_state_test_generators` utility. Note that this helper generates all available tests of `TESTGEN_FORKS` forks of `ALL_CONFIGS` configs of the given runner.
|
Here multiple phases load the configuration, and the stream of test cases is derived from a pytest file using the `eth2spec.gen_helpers.gen_from_tests.gen.run_state_test_generators` utility. Note that this helper generates all available tests of `TESTGEN_FORKS` forks of `ALL_CONFIGS` configs of the given runner.
|
||||||
|
@ -210,7 +210,7 @@ To add a new test generator that builds `New Tests`:
|
||||||
with any dependencies it may need. Leave it empty if your generator has none.
|
with any dependencies it may need. Leave it empty if your generator has none.
|
||||||
3. Your generator is assumed to have a `main.py` file in its root.
|
3. Your generator is assumed to have a `main.py` file in its root.
|
||||||
By adding the base generator to your requirements, you can make a generator really easily. See docs below.
|
By adding the base generator to your requirements, you can make a generator really easily. See docs below.
|
||||||
4. Your generator is called with `-o some/file/path/for_testing/can/be_anything -c some/other/path/to_configs/`.
|
4. Your generator is called with `-o some/file/path/for_testing/can/be_anything --preset-list mainnet minimal`.
|
||||||
The base generator helps you handle this; you only have to define test case providers.
|
The base generator helps you handle this; you only have to define test case providers.
|
||||||
5. Finally, add any linting or testing commands to the
|
5. Finally, add any linting or testing commands to the
|
||||||
[circleci config file](../../.circleci/config.yml) if desired to increase code quality.
|
[circleci config file](../../.circleci/config.yml) if desired to increase code quality.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods
|
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -31,6 +31,10 @@ if __name__ == "__main__":
|
||||||
# so no additional tests required.
|
# so no additional tests required.
|
||||||
capella_mods = bellatrix_mods
|
capella_mods = bellatrix_mods
|
||||||
|
|
||||||
|
# No epoch-processing changes in EIP4844 and previous testing repeats with new types,
|
||||||
|
# so no additional tests required.
|
||||||
|
eip4844_mods = capella_mods
|
||||||
|
|
||||||
# TODO Custody Game testgen is disabled for now
|
# TODO Custody Game testgen is disabled for now
|
||||||
# custody_game_mods = {**{key: 'eth2spec.test.custody_game.epoch_processing.test_process_' + key for key in [
|
# custody_game_mods = {**{key: 'eth2spec.test.custody_game.epoch_processing.test_process_' + key for key in [
|
||||||
# 'reveal_deadlines',
|
# 'reveal_deadlines',
|
||||||
|
@ -43,6 +47,7 @@ if __name__ == "__main__":
|
||||||
ALTAIR: altair_mods,
|
ALTAIR: altair_mods,
|
||||||
BELLATRIX: bellatrix_mods,
|
BELLATRIX: bellatrix_mods,
|
||||||
CAPELLA: capella_mods,
|
CAPELLA: capella_mods,
|
||||||
|
EIP4844: eip4844_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="epoch_processing", all_mods=all_mods)
|
run_state_test_generators(runner_name="epoch_processing", all_mods=all_mods)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators
|
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -7,12 +7,14 @@ if __name__ == "__main__":
|
||||||
altair_mods = phase_0_mods # No additional Altair specific finality tests
|
altair_mods = phase_0_mods # No additional Altair specific finality tests
|
||||||
bellatrix_mods = altair_mods # No additional Bellatrix specific finality tests
|
bellatrix_mods = altair_mods # No additional Bellatrix specific finality tests
|
||||||
capella_mods = bellatrix_mods # No additional Capella specific finality tests
|
capella_mods = bellatrix_mods # No additional Capella specific finality tests
|
||||||
|
eip4844_mods = capella_mods # No additional EIP4844 specific finality tests
|
||||||
|
|
||||||
all_mods = {
|
all_mods = {
|
||||||
PHASE0: phase_0_mods,
|
PHASE0: phase_0_mods,
|
||||||
ALTAIR: altair_mods,
|
ALTAIR: altair_mods,
|
||||||
BELLATRIX: bellatrix_mods,
|
BELLATRIX: bellatrix_mods,
|
||||||
CAPELLA: capella_mods,
|
CAPELLA: capella_mods,
|
||||||
|
EIP4844: eip4844_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="finality", all_mods=all_mods)
|
run_state_test_generators(runner_name="finality", all_mods=all_mods)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods
|
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -18,11 +18,14 @@ if __name__ == "__main__":
|
||||||
]}
|
]}
|
||||||
bellatrix_mods = combine_mods(_new_bellatrix_mods, altair_mods)
|
bellatrix_mods = combine_mods(_new_bellatrix_mods, altair_mods)
|
||||||
capella_mods = bellatrix_mods # No additional Capella specific fork choice tests
|
capella_mods = bellatrix_mods # No additional Capella specific fork choice tests
|
||||||
|
eip4844_mods = capella_mods # No additional Capella specific fork choice tests
|
||||||
|
|
||||||
all_mods = {
|
all_mods = {
|
||||||
PHASE0: phase_0_mods,
|
PHASE0: phase_0_mods,
|
||||||
ALTAIR: altair_mods,
|
ALTAIR: altair_mods,
|
||||||
BELLATRIX: bellatrix_mods,
|
BELLATRIX: bellatrix_mods,
|
||||||
CAPELLA: capella_mods,
|
CAPELLA: capella_mods,
|
||||||
|
EIP4844: eip4844_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="fork_choice", all_mods=all_mods)
|
run_state_test_generators(runner_name="fork_choice", all_mods=all_mods)
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
from eth2spec.test.helpers.constants import (
|
from eth2spec.test.helpers.constants import (
|
||||||
PHASE0, ALTAIR, BELLATRIX, CAPELLA,
|
PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844,
|
||||||
MINIMAL, MAINNET,
|
MINIMAL, MAINNET,
|
||||||
)
|
)
|
||||||
from eth2spec.test.helpers.typing import SpecForkName, PresetBaseName
|
from eth2spec.test.helpers.typing import SpecForkName, PresetBaseName
|
||||||
from eth2spec.test.altair.fork import test_altair_fork_basic, test_altair_fork_random
|
from eth2spec.test.altair.fork import test_altair_fork_basic, test_altair_fork_random
|
||||||
from eth2spec.test.bellatrix.fork import test_bellatrix_fork_basic, test_bellatrix_fork_random
|
from eth2spec.test.bellatrix.fork import test_bellatrix_fork_basic, test_bellatrix_fork_random
|
||||||
from eth2spec.test.capella.fork import test_capella_fork_basic, test_capella_fork_random
|
from eth2spec.test.capella.fork import test_capella_fork_basic, test_capella_fork_random
|
||||||
|
from eth2spec.test.eip4844.fork import test_eip4844_fork_basic, test_eip4844_fork_random
|
||||||
from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing
|
from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import generate_from_tests
|
from eth2spec.gen_helpers.gen_from_tests.gen import generate_from_tests
|
||||||
|
|
||||||
|
@ -39,6 +40,8 @@ def _get_fork_tests_providers():
|
||||||
yield create_provider(test_bellatrix_fork_random, preset, ALTAIR, BELLATRIX)
|
yield create_provider(test_bellatrix_fork_random, preset, ALTAIR, BELLATRIX)
|
||||||
yield create_provider(test_capella_fork_basic, preset, BELLATRIX, CAPELLA)
|
yield create_provider(test_capella_fork_basic, preset, BELLATRIX, CAPELLA)
|
||||||
yield create_provider(test_capella_fork_random, preset, BELLATRIX, CAPELLA)
|
yield create_provider(test_capella_fork_random, preset, BELLATRIX, CAPELLA)
|
||||||
|
yield create_provider(test_eip4844_fork_basic, preset, CAPELLA, EIP4844)
|
||||||
|
yield create_provider(test_eip4844_fork_random, preset, CAPELLA, EIP4844)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods
|
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -16,11 +16,13 @@ if __name__ == "__main__":
|
||||||
]}
|
]}
|
||||||
bellatrix_mods = combine_mods(_new_bellatrix_mods, altair_mods)
|
bellatrix_mods = combine_mods(_new_bellatrix_mods, altair_mods)
|
||||||
capella_mods = bellatrix_mods # No additional Capella specific genesis tests
|
capella_mods = bellatrix_mods # No additional Capella specific genesis tests
|
||||||
|
eip4844_mods = capella_mods # No additional EIP4844 specific genesis tests
|
||||||
all_mods = {
|
all_mods = {
|
||||||
PHASE0: phase_0_mods,
|
PHASE0: phase_0_mods,
|
||||||
ALTAIR: altair_mods,
|
ALTAIR: altair_mods,
|
||||||
BELLATRIX: bellatrix_mods,
|
BELLATRIX: bellatrix_mods,
|
||||||
CAPELLA: capella_mods,
|
CAPELLA: capella_mods,
|
||||||
|
EIP4844: eip4844_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="genesis", all_mods=all_mods)
|
run_state_test_generators(runner_name="genesis", all_mods=all_mods)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from eth2spec.test.helpers.constants import ALTAIR, BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import ALTAIR, BELLATRIX, CAPELLA, EIP4844
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators
|
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,11 +10,13 @@ if __name__ == "__main__":
|
||||||
]}
|
]}
|
||||||
bellatrix_mods = altair_mods
|
bellatrix_mods = altair_mods
|
||||||
capella_mods = bellatrix_mods
|
capella_mods = bellatrix_mods
|
||||||
|
eip4844_mods = capella_mods
|
||||||
|
|
||||||
all_mods = {
|
all_mods = {
|
||||||
ALTAIR: altair_mods,
|
ALTAIR: altair_mods,
|
||||||
BELLATRIX: bellatrix_mods,
|
BELLATRIX: bellatrix_mods,
|
||||||
CAPELLA: capella_mods,
|
CAPELLA: capella_mods,
|
||||||
|
EIP4844: eip4844_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="light_client", all_mods=all_mods)
|
run_state_test_generators(runner_name="light_client", all_mods=all_mods)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods
|
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -31,6 +31,12 @@ if __name__ == "__main__":
|
||||||
]}
|
]}
|
||||||
capella_mods = combine_mods(_new_capella_mods, bellatrix_mods)
|
capella_mods = combine_mods(_new_capella_mods, bellatrix_mods)
|
||||||
|
|
||||||
|
_new_eip4844_mods = {key: 'eth2spec.test.eip4844.block_processing.test_process_' + key for key in [
|
||||||
|
'bls_to_execution_change',
|
||||||
|
'withdrawals',
|
||||||
|
]}
|
||||||
|
eip4844_mods = combine_mods(_new_eip4844_mods, capella_mods)
|
||||||
|
|
||||||
# TODO Custody Game testgen is disabled for now
|
# TODO Custody Game testgen is disabled for now
|
||||||
# _new_custody_game_mods = {key: 'eth2spec.test.custody_game.block_processing.test_process_' + key for key in [
|
# _new_custody_game_mods = {key: 'eth2spec.test.custody_game.block_processing.test_process_' + key for key in [
|
||||||
# 'attestation',
|
# 'attestation',
|
||||||
|
@ -46,6 +52,7 @@ if __name__ == "__main__":
|
||||||
ALTAIR: altair_mods,
|
ALTAIR: altair_mods,
|
||||||
BELLATRIX: bellatrix_mods,
|
BELLATRIX: bellatrix_mods,
|
||||||
CAPELLA: capella_mods,
|
CAPELLA: capella_mods,
|
||||||
|
EIP4844: eip4844_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="operations", all_mods=all_mods)
|
run_state_test_generators(runner_name="operations", all_mods=all_mods)
|
||||||
|
|
|
@ -6,7 +6,9 @@ all:
|
||||||
rm -f ../../core/pyspec/eth2spec/test/altair/random/test_random.py
|
rm -f ../../core/pyspec/eth2spec/test/altair/random/test_random.py
|
||||||
rm -f ../../core/pyspec/eth2spec/test/bellatrix/random/test_random.py
|
rm -f ../../core/pyspec/eth2spec/test/bellatrix/random/test_random.py
|
||||||
rm -f ../../core/pyspec/eth2spec/test/capella/random/test_random.py
|
rm -f ../../core/pyspec/eth2spec/test/capella/random/test_random.py
|
||||||
|
rm -f ../../core/pyspec/eth2spec/test/eip4844/random/test_random.py
|
||||||
python3 generate.py phase0 > ../../core/pyspec/eth2spec/test/phase0/random/test_random.py
|
python3 generate.py phase0 > ../../core/pyspec/eth2spec/test/phase0/random/test_random.py
|
||||||
python3 generate.py altair > ../../core/pyspec/eth2spec/test/altair/random/test_random.py
|
python3 generate.py altair > ../../core/pyspec/eth2spec/test/altair/random/test_random.py
|
||||||
python3 generate.py bellatrix > ../../core/pyspec/eth2spec/test/bellatrix/random/test_random.py
|
python3 generate.py bellatrix > ../../core/pyspec/eth2spec/test/bellatrix/random/test_random.py
|
||||||
python3 generate.py capella > ../../core/pyspec/eth2spec/test/capella/random/test_random.py
|
python3 generate.py capella > ../../core/pyspec/eth2spec/test/capella/random/test_random.py
|
||||||
|
python3 generate.py eip4844 > ../../core/pyspec/eth2spec/test/eip4844/random/test_random.py
|
||||||
|
|
|
@ -21,10 +21,12 @@ from eth2spec.test.utils.randomized_block_tests import (
|
||||||
randomize_state_altair,
|
randomize_state_altair,
|
||||||
randomize_state_bellatrix,
|
randomize_state_bellatrix,
|
||||||
randomize_state_capella,
|
randomize_state_capella,
|
||||||
|
randomize_state_eip4844,
|
||||||
random_block,
|
random_block,
|
||||||
random_block_altair_with_cycling_sync_committee_participation,
|
random_block_altair_with_cycling_sync_committee_participation,
|
||||||
random_block_bellatrix,
|
random_block_bellatrix,
|
||||||
random_block_capella,
|
random_block_capella,
|
||||||
|
random_block_eip4844,
|
||||||
last_slot_in_epoch,
|
last_slot_in_epoch,
|
||||||
random_slot_in_epoch,
|
random_slot_in_epoch,
|
||||||
penultimate_slot_in_epoch,
|
penultimate_slot_in_epoch,
|
||||||
|
@ -34,7 +36,7 @@ from eth2spec.test.utils.randomized_block_tests import (
|
||||||
transition_to_leaking,
|
transition_to_leaking,
|
||||||
transition_without_leak,
|
transition_without_leak,
|
||||||
)
|
)
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844
|
||||||
|
|
||||||
|
|
||||||
# Ensure this many blocks are present in *each* randomized scenario
|
# Ensure this many blocks are present in *each* randomized scenario
|
||||||
|
@ -272,5 +274,12 @@ if __name__ == "__main__":
|
||||||
state_randomizer=randomize_state_capella,
|
state_randomizer=randomize_state_capella,
|
||||||
block_randomizer=random_block_capella,
|
block_randomizer=random_block_capella,
|
||||||
)
|
)
|
||||||
|
if EIP4844 in sys.argv:
|
||||||
|
did_generate = True
|
||||||
|
run_generate_tests_to_std_out(
|
||||||
|
EIP4844,
|
||||||
|
state_randomizer=randomize_state_eip4844,
|
||||||
|
block_randomizer=random_block_eip4844,
|
||||||
|
)
|
||||||
if not did_generate:
|
if not did_generate:
|
||||||
warnings.warn("no phase given for test generation")
|
warnings.warn("no phase given for test generation")
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators
|
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,12 +15,16 @@ if __name__ == "__main__":
|
||||||
capella_mods = {key: 'eth2spec.test.capella.random.test_' + key for key in [
|
capella_mods = {key: 'eth2spec.test.capella.random.test_' + key for key in [
|
||||||
'random',
|
'random',
|
||||||
]}
|
]}
|
||||||
|
eip4844_mods = {key: 'eth2spec.test.eip4844.random.test_' + key for key in [
|
||||||
|
'random',
|
||||||
|
]}
|
||||||
|
|
||||||
all_mods = {
|
all_mods = {
|
||||||
PHASE0: phase_0_mods,
|
PHASE0: phase_0_mods,
|
||||||
ALTAIR: altair_mods,
|
ALTAIR: altair_mods,
|
||||||
BELLATRIX: bellatrix_mods,
|
BELLATRIX: bellatrix_mods,
|
||||||
CAPELLA: capella_mods,
|
CAPELLA: capella_mods,
|
||||||
|
EIP4844: eip4844_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="random", all_mods=all_mods)
|
run_state_test_generators(runner_name="random", all_mods=all_mods)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators
|
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -16,12 +16,14 @@ if __name__ == "__main__":
|
||||||
# Transaction fees are part of the execution-layer.
|
# Transaction fees are part of the execution-layer.
|
||||||
bellatrix_mods = altair_mods
|
bellatrix_mods = altair_mods
|
||||||
capella_mods = bellatrix_mods
|
capella_mods = bellatrix_mods
|
||||||
|
eip4844_mods = capella_mods
|
||||||
|
|
||||||
all_mods = {
|
all_mods = {
|
||||||
PHASE0: phase_0_mods,
|
PHASE0: phase_0_mods,
|
||||||
ALTAIR: altair_mods,
|
ALTAIR: altair_mods,
|
||||||
BELLATRIX: bellatrix_mods,
|
BELLATRIX: bellatrix_mods,
|
||||||
CAPELLA: capella_mods,
|
CAPELLA: capella_mods,
|
||||||
|
EIP4844: eip4844_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="rewards", all_mods=all_mods)
|
run_state_test_generators(runner_name="rewards", all_mods=all_mods)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR, BELLATRIX, CAPELLA, EIP4844
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods
|
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,11 +23,17 @@ if __name__ == "__main__":
|
||||||
]}
|
]}
|
||||||
capella_mods = combine_mods(_new_capella_mods, bellatrix_mods)
|
capella_mods = combine_mods(_new_capella_mods, bellatrix_mods)
|
||||||
|
|
||||||
|
_new_eip4844_mods = {key: 'eth2spec.test.eip4844.sanity.test_' + key for key in [
|
||||||
|
'blocks',
|
||||||
|
]}
|
||||||
|
eip4844_mods = combine_mods(_new_eip4844_mods, capella_mods)
|
||||||
|
|
||||||
all_mods = {
|
all_mods = {
|
||||||
PHASE0: phase_0_mods,
|
PHASE0: phase_0_mods,
|
||||||
ALTAIR: altair_mods,
|
ALTAIR: altair_mods,
|
||||||
BELLATRIX: bellatrix_mods,
|
BELLATRIX: bellatrix_mods,
|
||||||
CAPELLA: capella_mods,
|
CAPELLA: capella_mods,
|
||||||
|
EIP4844: eip4844_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="sanity", all_mods=all_mods)
|
run_state_test_generators(runner_name="sanity", all_mods=all_mods)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators
|
from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators
|
||||||
from eth2spec.test.helpers.constants import BELLATRIX, CAPELLA
|
from eth2spec.test.helpers.constants import BELLATRIX, CAPELLA, EIP4844
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -7,10 +7,12 @@ if __name__ == "__main__":
|
||||||
'optimistic',
|
'optimistic',
|
||||||
]}
|
]}
|
||||||
capella_mods = bellatrix_mods
|
capella_mods = bellatrix_mods
|
||||||
|
eip4844_mods = capella_mods
|
||||||
|
|
||||||
all_mods = {
|
all_mods = {
|
||||||
BELLATRIX: bellatrix_mods,
|
BELLATRIX: bellatrix_mods,
|
||||||
CAPELLA: capella_mods,
|
CAPELLA: capella_mods,
|
||||||
|
EIP4844: eip4844_mods,
|
||||||
}
|
}
|
||||||
|
|
||||||
run_state_test_generators(runner_name="sync", all_mods=all_mods)
|
run_state_test_generators(runner_name="sync", all_mods=all_mods)
|
||||||
|
|
Loading…
Reference in New Issue