diff --git a/setup.py b/setup.py index 6013eff756..c9041010d1 100644 --- a/setup.py +++ b/setup.py @@ -1101,10 +1101,6 @@ def finalize_options(self): """ if self.spec_fork == EIP6110: self.md_doc_paths += """ - specs/_features/eip6110/light-client/fork.md - specs/_features/eip6110/light-client/full-node.md - specs/_features/eip6110/light-client/p2p-interface.md - specs/_features/eip6110/light-client/sync-protocol.md specs/_features/eip6110/beacon-chain.md specs/_features/eip6110/fork.md """ diff --git a/specs/_features/eip6110/beacon-chain.md b/specs/_features/eip6110/beacon-chain.md index e1384fdae0..1bfa29138a 100644 --- a/specs/_features/eip6110/beacon-chain.md +++ b/specs/_features/eip6110/beacon-chain.md @@ -91,7 +91,8 @@ class ExecutionPayload(Container): block_hash: Hash32 transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD] withdrawals: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD] - excess_data_gas: uint256 + data_gas_used: uint64 + excess_data_gas: uint64 deposit_receipts: List[DepositReceipt, MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD] # [New in EIP6110] ``` @@ -116,7 +117,8 @@ class ExecutionPayloadHeader(Container): block_hash: Hash32 transactions_root: Root withdrawals_root: Root - excess_data_gas: uint256 + data_gas_used: uint64 + excess_data_gas: uint64 deposit_receipts_root: Root # [New in EIP6110] ``` @@ -268,6 +270,7 @@ def process_execution_payload(state: BeaconState, body: BeaconBlockBody, executi block_hash=payload.block_hash, transactions_root=hash_tree_root(payload.transactions), withdrawals_root=hash_tree_root(payload.withdrawals), + data_gas_used=payload.data_gas_used, excess_data_gas=payload.excess_data_gas, deposit_receipts_root=hash_tree_root(payload.deposit_receipts), # [New in EIP6110] ) diff --git a/specs/_features/eip6110/fork.md b/specs/_features/eip6110/fork.md index 2145a9d1a3..b3b14a3f8c 100644 --- a/specs/_features/eip6110/fork.md +++ b/specs/_features/eip6110/fork.md @@ -88,7 +88,8 @@ def upgrade_to_eip6110(pre: deneb.BeaconState) -> BeaconState: 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, - excess_data_gas=uint256(0), + data_gas_used=uint64(0), + excess_data_gas=uint64(0), deposit_receipts_root=Root(), # [New in EIP-6110] ) post = BeaconState( diff --git a/specs/_features/eip6110/light-client/fork.md b/specs/_features/eip6110/light-client/fork.md deleted file mode 100644 index 34f0fef8ce..0000000000 --- a/specs/_features/eip6110/light-client/fork.md +++ /dev/null @@ -1,112 +0,0 @@ -# EIP-6110 Light Client -- Fork Logic - -## Table of contents - - - - - -- [Introduction](#introduction) - - [Upgrading light client data](#upgrading-light-client-data) - - [Upgrading the store](#upgrading-the-store) - - - - -## Introduction - -This document describes how to upgrade existing light client objects based on the [Deneb specification](../../deneb/light-client/sync-protocol.md) to eip6110. This is necessary when processing pre-eip6110 data with a post-eip6110 `LightClientStore`. Note that the data being exchanged over the network protocols uses the original format. - -### Upgrading light client data - -A eip6110 `LightClientStore` can still process earlier light client data. In order to do so, that pre-eip6110 data needs to be locally upgraded to eip6110 before processing. - -```python -def upgrade_lc_header_to_eip6110(pre: deneb.LightClientHeader) -> LightClientHeader: - return LightClientHeader( - beacon=pre.beacon, - execution=ExecutionPayloadHeader( - parent_hash=pre.execution.parent_hash, - fee_recipient=pre.execution.fee_recipient, - state_root=pre.execution.state_root, - receipts_root=pre.execution.receipts_root, - logs_bloom=pre.execution.logs_bloom, - prev_randao=pre.execution.prev_randao, - block_number=pre.execution.block_number, - gas_limit=pre.execution.gas_limit, - gas_used=pre.execution.gas_used, - timestamp=pre.execution.timestamp, - extra_data=pre.execution.extra_data, - base_fee_per_gas=pre.execution.base_fee_per_gas, - block_hash=pre.execution.block_hash, - transactions_root=pre.execution.transactions_root, - withdrawals_root=pre.execution.withdrawals_root, - excess_data_gas=pre.execution.excess_data_gas, - deposit_receipts_root=Root(), # [New in EIP6110] - ), - execution_branch=pre.execution_branch, - ) -``` - -```python -def upgrade_lc_bootstrap_to_eip6110(pre: deneb.LightClientBootstrap) -> LightClientBootstrap: - return LightClientBootstrap( - header=upgrade_lc_header_to_eip6110(pre.header), - current_sync_committee=pre.current_sync_committee, - current_sync_committee_branch=pre.current_sync_committee_branch, - ) -``` - -```python -def upgrade_lc_update_to_eip6110(pre: deneb.LightClientUpdate) -> LightClientUpdate: - return LightClientUpdate( - attested_header=upgrade_lc_header_to_eip6110(pre.attested_header), - next_sync_committee=pre.next_sync_committee, - next_sync_committee_branch=pre.next_sync_committee_branch, - finalized_header=upgrade_lc_header_to_eip6110(pre.finalized_header), - finality_branch=pre.finality_branch, - sync_aggregate=pre.sync_aggregate, - signature_slot=pre.signature_slot, - ) -``` - -```python -def upgrade_lc_finality_update_to_eip6110(pre: deneb.LightClientFinalityUpdate) -> LightClientFinalityUpdate: - return LightClientFinalityUpdate( - attested_header=upgrade_lc_header_to_eip6110(pre.attested_header), - finalized_header=upgrade_lc_header_to_eip6110(pre.finalized_header), - finality_branch=pre.finality_branch, - sync_aggregate=pre.sync_aggregate, - signature_slot=pre.signature_slot, - ) -``` - -```python -def upgrade_lc_optimistic_update_to_eip6110(pre: deneb.LightClientOptimisticUpdate) -> LightClientOptimisticUpdate: - return LightClientOptimisticUpdate( - attested_header=upgrade_lc_header_to_eip6110(pre.attested_header), - sync_aggregate=pre.sync_aggregate, - signature_slot=pre.signature_slot, - ) -``` - -### Upgrading the store - -Existing `LightClientStore` objects based on Deneb MUST be upgraded to eip6110 before eip6110 based light client data can be processed. The `LightClientStore` upgrade MAY be performed before `EIP6110_FORK_EPOCH`. - -```python -def upgrade_lc_store_to_eip6110(pre: deneb.LightClientStore) -> LightClientStore: - if pre.best_valid_update is None: - best_valid_update = None - else: - best_valid_update = upgrade_lc_update_to_eip6110(pre.best_valid_update) - return LightClientStore( - finalized_header=upgrade_lc_header_to_eip6110(pre.finalized_header), - current_sync_committee=pre.current_sync_committee, - next_sync_committee=pre.next_sync_committee, - best_valid_update=best_valid_update, - optimistic_header=upgrade_lc_header_to_eip6110(pre.optimistic_header), - previous_max_active_participants=pre.previous_max_active_participants, - current_max_active_participants=pre.current_max_active_participants, - ) -``` diff --git a/specs/_features/eip6110/light-client/full-node.md b/specs/_features/eip6110/light-client/full-node.md deleted file mode 100644 index 03c0f17bd8..0000000000 --- a/specs/_features/eip6110/light-client/full-node.md +++ /dev/null @@ -1,77 +0,0 @@ -# EIP-6110 Light Client -- Full Node - -**Notice**: This document is a work-in-progress for researchers and implementers. - -## Table of contents - - - - - -- [Introduction](#introduction) -- [Helper functions](#helper-functions) - - [Modified `block_to_light_client_header`](#modified-block_to_light_client_header) - - - - -## Introduction - -This upgrade adds information about the execution payload to light client data as part of the EIP-6110 upgrade. - -## Helper functions - -### Modified `block_to_light_client_header` - -```python -def block_to_light_client_header(block: SignedBeaconBlock) -> LightClientHeader: - epoch = compute_epoch_at_slot(block.message.slot) - - if epoch >= CAPELLA_FORK_EPOCH: - payload = block.message.body.execution_payload - execution_header = ExecutionPayloadHeader( - parent_hash=payload.parent_hash, - fee_recipient=payload.fee_recipient, - state_root=payload.state_root, - receipts_root=payload.receipts_root, - logs_bloom=payload.logs_bloom, - prev_randao=payload.prev_randao, - block_number=payload.block_number, - gas_limit=payload.gas_limit, - gas_used=payload.gas_used, - timestamp=payload.timestamp, - extra_data=payload.extra_data, - base_fee_per_gas=payload.base_fee_per_gas, - block_hash=payload.block_hash, - transactions_root=hash_tree_root(payload.transactions), - withdrawals_root=hash_tree_root(payload.withdrawals), - ) - - if epoch >= DENEB_FORK_EPOCH: - execution_header.excess_data_gas = payload.excess_data_gas - - # [New in EIP6110] - if epoch >= EIP6110_FORK_EPOCH: - execution_header.deposit_receipts_root = hash_tree_root(payload.deposit_receipts) - - execution_branch = compute_merkle_proof_for_block_body(block.message.body, EXECUTION_PAYLOAD_INDEX) - else: - # Note that during fork transitions, `finalized_header` may still point to earlier forks. - # While Bellatrix blocks also contain an `ExecutionPayload` (minus `withdrawals_root`), - # it was not included in the corresponding light client data. To ensure compatibility - # with legacy data going through `upgrade_lc_header_to_capella`, leave out execution data. - execution_header = ExecutionPayloadHeader() - execution_branch = [Bytes32() for _ in range(floorlog2(EXECUTION_PAYLOAD_INDEX))] - - return LightClientHeader( - beacon=BeaconBlockHeader( - slot=block.message.slot, - proposer_index=block.message.proposer_index, - parent_root=block.message.parent_root, - state_root=block.message.state_root, - body_root=hash_tree_root(block.message.body), - ), - execution=execution_header, - execution_branch=execution_branch, - ) -``` diff --git a/specs/_features/eip6110/light-client/p2p-interface.md b/specs/_features/eip6110/light-client/p2p-interface.md deleted file mode 100644 index f55fb2f77e..0000000000 --- a/specs/_features/eip6110/light-client/p2p-interface.md +++ /dev/null @@ -1,111 +0,0 @@ -# EIP-6110 Light Client -- Networking - -**Notice**: This document is a work-in-progress for researchers and implementers. - -## Table of contents - - - - - -- [Networking](#networking) - - [The gossip domain: gossipsub](#the-gossip-domain-gossipsub) - - [Topics and messages](#topics-and-messages) - - [Global topics](#global-topics) - - [`light_client_finality_update`](#light_client_finality_update) - - [`light_client_optimistic_update`](#light_client_optimistic_update) - - [The Req/Resp domain](#the-reqresp-domain) - - [Messages](#messages) - - [GetLightClientBootstrap](#getlightclientbootstrap) - - [LightClientUpdatesByRange](#lightclientupdatesbyrange) - - [GetLightClientFinalityUpdate](#getlightclientfinalityupdate) - - [GetLightClientOptimisticUpdate](#getlightclientoptimisticupdate) - - - - -## Networking - -The [Deneb light client networking specification](../../deneb/light-client/p2p-interface.md) is extended to exchange [EIP-6110 light client data](./sync-protocol.md). - -### The gossip domain: gossipsub - -#### Topics and messages - -##### Global topics - -###### `light_client_finality_update` - -[0]: # (eth2spec: skip) - -| `fork_version` | Message SSZ type | -|--------------------------------------------------------|-------------------------------------| -| `GENESIS_FORK_VERSION` | n/a | -| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientFinalityUpdate` | -| `CAPELLA_FORK_VERSION` | `capella.LightClientFinalityUpdate` | -| `DENEB_FORK_VERSION` | `deneb.LightClientFinalityUpdate` | -| `EIP6110_FORK_VERSION` and later | `eip6110.LightClientFinalityUpdate` | - -###### `light_client_optimistic_update` - -[0]: # (eth2spec: skip) - -| `fork_version` | Message SSZ type | -|--------------------------------------------------------|---------------------------------------| -| `GENESIS_FORK_VERSION` | n/a | -| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientOptimisticUpdate` | -| `CAPELLA_FORK_VERSION` | `capella.LightClientOptimisticUpdate` | -| `DENEB_FORK_VERSION` | `deneb.LightClientOptimisticUpdate` | -| `EIP6110_FORK_VERSION` and later | `eip6110.LightClientOptimisticUpdate` | - -### The Req/Resp domain - -#### Messages - -##### GetLightClientBootstrap - -[0]: # (eth2spec: skip) - -| `fork_version` | Response SSZ type | -|--------------------------------------------------------|------------------------------------| -| `GENESIS_FORK_VERSION` | n/a | -| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientBootstrap` | -| `CAPELLA_FORK_VERSION` | `capella.LightClientBootstrap` | -| `DENEB_FORK_VERSION` | `deneb.LightClientBootstrap` | -| `EIP6110_FORK_VERSION` and later | `eip6110.LightClientBootstrap` | - -##### LightClientUpdatesByRange - -[0]: # (eth2spec: skip) - -| `fork_version` | Response chunk SSZ type | -|--------------------------------------------------------|----------------------------------| -| `GENESIS_FORK_VERSION` | n/a | -| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientUpdate` | -| `CAPELLA_FORK_VERSION` | `capella.LightClientUpdate` | -| `DENEB_FORK_VERSION` | `deneb.LightClientUpdate` | -| `EIP6110_FORK_VERSION` and later | `eip6110.LightClientUpdate` | - -##### GetLightClientFinalityUpdate - -[0]: # (eth2spec: skip) - -| `fork_version` | Response SSZ type | -|--------------------------------------------------------|-------------------------------------| -| `GENESIS_FORK_VERSION` | n/a | -| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientFinalityUpdate` | -| `CAPELLA_FORK_VERSION` | `capella.LightClientFinalityUpdate` | -| `DENEB_FORK_VERSION` | `deneb.LightClientFinalityUpdate` | -| `EIP6110_FORK_VERSION` and later | `eip6110.LightClientFinalityUpdate` | - -##### GetLightClientOptimisticUpdate - -[0]: # (eth2spec: skip) - -| `fork_version` | Response SSZ type | -|--------------------------------------------------------|---------------------------------------| -| `GENESIS_FORK_VERSION` | n/a | -| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientOptimisticUpdate` | -| `CAPELLA_FORK_VERSION` | `capella.LightClientOptimisticUpdate` | -| `DENEB_FORK_VERSION` | `deneb.LightClientOptimisticUpdate` | -| `EIP6110_FORK_VERSION` and later | `eip6110.LightClientOptimisticUpdate` | diff --git a/specs/_features/eip6110/light-client/sync-protocol.md b/specs/_features/eip6110/light-client/sync-protocol.md deleted file mode 100644 index bcb9d50e43..0000000000 --- a/specs/_features/eip6110/light-client/sync-protocol.md +++ /dev/null @@ -1,89 +0,0 @@ -# EIP-6110 Light Client -- Sync Protocol - -**Notice**: This document is a work-in-progress for researchers and implementers. - -## Table of contents - - - - - -- [Introduction](#introduction) -- [Helper functions](#helper-functions) - - [Modified `get_lc_execution_root`](#modified-get_lc_execution_root) - - [Modified `is_valid_light_client_header`](#modified-is_valid_light_client_header) - - - - -## Introduction - -This upgrade updates light client data to include the EIP-6110 changes to the [`ExecutionPayload`](../beacon-chain.md) structure. It extends the [Deneb Light Client specifications](../../deneb/light-client/sync-protocol.md). The [fork document](./fork.md) explains how to upgrade existing Deneb based deployments to EIP-6110. - -Additional documents describes the impact of the upgrade on certain roles: -- [Full node](./full-node.md) -- [Networking](./p2p-interface.md) - -## Helper functions - -### Modified `get_lc_execution_root` - -```python -def get_lc_execution_root(header: LightClientHeader) -> Root: - epoch = compute_epoch_at_slot(header.beacon.slot) - - if epoch >= DENEB_FORK_EPOCH: - return hash_tree_root(header.execution) - - if epoch >= CAPELLA_FORK_EPOCH: - execution_header = capella.ExecutionPayloadHeader( - parent_hash=header.execution.parent_hash, - fee_recipient=header.execution.fee_recipient, - state_root=header.execution.state_root, - receipts_root=header.execution.receipts_root, - logs_bloom=header.execution.logs_bloom, - prev_randao=header.execution.prev_randao, - block_number=header.execution.block_number, - gas_limit=header.execution.gas_limit, - gas_used=header.execution.gas_used, - timestamp=header.execution.timestamp, - extra_data=header.execution.extra_data, - base_fee_per_gas=header.execution.base_fee_per_gas, - block_hash=header.execution.block_hash, - transactions_root=header.execution.transactions_root, - withdrawals_root=header.execution.withdrawals_root, - ) - return hash_tree_root(execution_header) - - return Root() -``` - -### Modified `is_valid_light_client_header` - -```python -def is_valid_light_client_header(header: LightClientHeader) -> bool: - epoch = compute_epoch_at_slot(header.beacon.slot) - - # [New in EIP-6110] - if epoch < EIP6110_FORK_EPOCH: - if header.execution.deposit_receipts_root != Root(): - return False - - if epoch < DENEB_FORK_EPOCH: - if header.execution.excess_data_gas != uint256(0): - return False - - if epoch < CAPELLA_FORK_EPOCH: - return ( - header.execution == ExecutionPayloadHeader() - and header.execution_branch == [Bytes32() for _ in range(floorlog2(EXECUTION_PAYLOAD_INDEX))] - ) - - return is_valid_merkle_branch( - leaf=get_lc_execution_root(header), - branch=header.execution_branch, - depth=floorlog2(EXECUTION_PAYLOAD_INDEX), - index=get_subtree_index(EXECUTION_PAYLOAD_INDEX), - root=header.beacon.body_root, - ) -``` diff --git a/specs/deneb/beacon-chain.md b/specs/deneb/beacon-chain.md index 175a80edf5..489ae6151c 100644 --- a/specs/deneb/beacon-chain.md +++ b/specs/deneb/beacon-chain.md @@ -126,7 +126,8 @@ class ExecutionPayload(Container): block_hash: Hash32 # Hash of execution block transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD] withdrawals: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD] - excess_data_gas: uint256 # [New in Deneb] + data_gas_used: uint64 # [New in Deneb] + excess_data_gas: uint64 # [New in Deneb] ``` #### `ExecutionPayloadHeader` @@ -150,7 +151,8 @@ class ExecutionPayloadHeader(Container): block_hash: Hash32 # Hash of execution block transactions_root: Root withdrawals_root: Root - excess_data_gas: uint256 # [New in Deneb] + data_gas_used: uint64 # [New in Deneb] + excess_data_gas: uint64 # [New in Deneb] ``` ## Helper functions @@ -257,6 +259,7 @@ def process_execution_payload(state: BeaconState, body: BeaconBlockBody, executi block_hash=payload.block_hash, transactions_root=hash_tree_root(payload.transactions), withdrawals_root=hash_tree_root(payload.withdrawals), + data_gas_used=payload.data_gas_used, # [New in Deneb] excess_data_gas=payload.excess_data_gas, # [New in Deneb] ) ``` diff --git a/specs/deneb/fork-choice.md b/specs/deneb/fork-choice.md index c70a6e8d13..283e76b1df 100644 --- a/specs/deneb/fork-choice.md +++ b/specs/deneb/fork-choice.md @@ -8,7 +8,6 @@ - [Introduction](#introduction) - [Containers](#containers) - [Helpers](#helpers) - - [`validate_blobs`](#validate_blobs) - [`is_data_available`](#is_data_available) - [Updated fork-choice handlers](#updated-fork-choice-handlers) - [`on_block`](#on_block) @@ -24,21 +23,10 @@ This is the modification of the fork choice accompanying the Deneb upgrade. ## Helpers -#### `validate_blobs` - -```python -def validate_blobs(expected_kzg_commitments: Sequence[KZGCommitment], - blobs: Sequence[Blob], - proofs: Sequence[KZGProof]) -> None: - assert len(expected_kzg_commitments) == len(blobs) == len(proofs) - - assert verify_blob_kzg_proof_batch(blobs, expected_kzg_commitments, proofs) -``` - #### `is_data_available` The implementation of `is_data_available` will become more sophisticated during later scaling upgrades. -Initially, verification requires every verifying actor to retrieve all matching `Blob`s and `KZGProof`s, and validate them with `validate_blobs`. +Initially, verification requires every verifying actor to retrieve all matching `Blob`s and `KZGProof`s, and validate them with `verify_blob_kzg_proof_batch`. The block MUST NOT be considered valid until all valid `Blob`s have been downloaded. Blocks that have been previously validated as available SHOULD be considered available even if the associated `Blob`s have subsequently been pruned. @@ -54,7 +42,7 @@ def is_data_available(beacon_block_root: Root, blob_kzg_commitments: Sequence[KZ if isinstance(blobs, str) or isinstance(proofs, str): return True - validate_blobs(blob_kzg_commitments, blobs, proofs) + assert verify_blob_kzg_proof_batch(blobs, blob_kzg_commitments, proofs) return True ``` diff --git a/specs/deneb/fork.md b/specs/deneb/fork.md index 23b3f23c7b..7fc80275d6 100644 --- a/specs/deneb/fork.md +++ b/specs/deneb/fork.md @@ -83,7 +83,8 @@ def upgrade_to_deneb(pre: capella.BeaconState) -> BeaconState: 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, - excess_data_gas=uint256(0), # [New in Deneb] + data_gas_used=uint64(0), # [New in Deneb] + excess_data_gas=uint64(0), # [New in Deneb] ) post = BeaconState( # Versioning diff --git a/specs/deneb/light-client/fork.md b/specs/deneb/light-client/fork.md index 46a0930283..2fd410fc56 100644 --- a/specs/deneb/light-client/fork.md +++ b/specs/deneb/light-client/fork.md @@ -41,7 +41,8 @@ def upgrade_lc_header_to_deneb(pre: capella.LightClientHeader) -> LightClientHea block_hash=pre.execution.block_hash, transactions_root=pre.execution.transactions_root, withdrawals_root=pre.execution.withdrawals_root, - excess_data_gas=uint256(0), # [New in Deneb] + data_gas_used=uint64(0), # [New in Deneb] + excess_data_gas=uint64(0), # [New in Deneb] ), execution_branch=pre.execution_branch, ) diff --git a/specs/deneb/light-client/full-node.md b/specs/deneb/light-client/full-node.md index 2751940366..69ba0d3bab 100644 --- a/specs/deneb/light-client/full-node.md +++ b/specs/deneb/light-client/full-node.md @@ -49,6 +49,7 @@ def block_to_light_client_header(block: SignedBeaconBlock) -> LightClientHeader: # [New in Deneb] if epoch >= DENEB_FORK_EPOCH: + execution_header.data_gas_used = payload.data_gas_used execution_header.excess_data_gas = payload.excess_data_gas execution_branch = compute_merkle_proof_for_block_body(block.message.body, EXECUTION_PAYLOAD_INDEX) diff --git a/specs/deneb/light-client/sync-protocol.md b/specs/deneb/light-client/sync-protocol.md index c691a113da..b7b9b5ab1f 100644 --- a/specs/deneb/light-client/sync-protocol.md +++ b/specs/deneb/light-client/sync-protocol.md @@ -68,7 +68,7 @@ def is_valid_light_client_header(header: LightClientHeader) -> bool: # [New in Deneb] if epoch < DENEB_FORK_EPOCH: - if header.execution.excess_data_gas != uint256(0): + if header.execution.data_gas_used != uint64(0) or header.execution.excess_data_gas != uint64(0): return False if epoch < CAPELLA_FORK_EPOCH: diff --git a/specs/deneb/p2p-interface.md b/specs/deneb/p2p-interface.md index 2d6454737f..caf2b5baea 100644 --- a/specs/deneb/p2p-interface.md +++ b/specs/deneb/p2p-interface.md @@ -269,7 +269,7 @@ Requests blob sidecars in the slot range `[start_slot, start_slot + count)`, lea The response is unsigned, i.e. `BlobSidecarsByRange`, as the signature of the beacon block proposer may not be available beyond the initial distribution via gossip. -Before consuming the next response chunk, the response reader SHOULD verify the blob sidecar is well-formatted and correct w.r.t. the expected KZG commitments through `validate_blobs`. +Before consuming the next response chunk, the response reader SHOULD verify the blob sidecar is well-formatted and correct w.r.t. the expected KZG commitments through `verify_blob_kzg_proof_batch`. `BlobSidecarsByRange` is primarily used to sync blobs that may have been missed on gossip and to sync within the `MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS` window. diff --git a/tests/core/pyspec/eth2spec/VERSION.txt b/tests/core/pyspec/eth2spec/VERSION.txt index 7792609910..2a6fa03c08 100644 --- a/tests/core/pyspec/eth2spec/VERSION.txt +++ b/tests/core/pyspec/eth2spec/VERSION.txt @@ -1 +1 @@ -1.4.0-alpha.0 +1.4.0-alpha.1 diff --git a/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py b/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py index 5d802bbb3e..7e9c6b7e2f 100644 --- a/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py +++ b/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py @@ -1,12 +1,12 @@ from eth2spec.test.context import ( spec_state_test, - with_altair_and_later, + with_light_client, with_test_suite_name, ) @with_test_suite_name("BeaconState") -@with_altair_and_later +@with_light_client @spec_state_test def test_current_sync_committee_merkle_proof(spec, state): yield "object", state @@ -27,7 +27,7 @@ def test_current_sync_committee_merkle_proof(spec, state): @with_test_suite_name("BeaconState") -@with_altair_and_later +@with_light_client @spec_state_test def test_next_sync_committee_merkle_proof(spec, state): yield "object", state @@ -48,7 +48,7 @@ def test_next_sync_committee_merkle_proof(spec, state): @with_test_suite_name("BeaconState") -@with_altair_and_later +@with_light_client @spec_state_test def test_finality_root_merkle_proof(spec, state): yield "object", state diff --git a/tests/core/pyspec/eth2spec/test/altair/light_client/test_sync.py b/tests/core/pyspec/eth2spec/test/altair/light_client/test_sync.py index 1a527a767a..f8faa2fdda 100644 --- a/tests/core/pyspec/eth2spec/test/altair/light_client/test_sync.py +++ b/tests/core/pyspec/eth2spec/test/altair/light_client/test_sync.py @@ -9,7 +9,7 @@ with_phases, with_presets, with_state, - with_altair_and_later, + with_light_client, ) from eth2spec.test.helpers.attestations import ( next_slots_with_attestations, @@ -26,7 +26,6 @@ from eth2spec.test.helpers.forks import ( is_post_capella, is_post_deneb, is_post_fork, - is_post_eip6110, ) from eth2spec.test.helpers.light_client import ( get_sync_aggregate, @@ -58,10 +57,6 @@ def needs_upgrade_to_deneb(d_spec, s_spec): return is_post_deneb(s_spec) and not is_post_deneb(d_spec) -def needs_upgrade_to_eip6110(d_spec, s_spec): - return is_post_eip6110(s_spec) and not is_post_eip6110(d_spec) - - def check_lc_header_equal(d_spec, s_spec, data, upgraded): assert upgraded.beacon.slot == data.beacon.slot assert upgraded.beacon.hash_tree_root() == data.beacon.hash_tree_root() @@ -89,10 +84,6 @@ def upgrade_lc_bootstrap_to_store(d_spec, s_spec, data): upgraded = s_spec.upgrade_lc_bootstrap_to_deneb(upgraded) check_lc_bootstrap_equal(d_spec, s_spec, data, upgraded) - if needs_upgrade_to_eip6110(d_spec, s_spec): - upgraded = s_spec.upgrade_lc_bootstrap_to_eip6110(upgraded) - check_lc_bootstrap_equal(d_spec, s_spec, data, upgraded) - return upgraded @@ -154,8 +145,6 @@ class LightClientSyncTest(object): def get_store_fork_version(s_spec): - if is_post_eip6110(s_spec): - return s_spec.config.EIP6110_FORK_VERSION if is_post_deneb(s_spec): return s_spec.config.DENEB_FORK_VERSION if is_post_capella(s_spec): @@ -301,7 +290,7 @@ def compute_start_slot_at_next_sync_committee_period(spec, state): return compute_start_slot_at_sync_committee_period(spec, sync_committee_period + 1) -@with_altair_and_later +@with_light_client @spec_state_test_with_matching_config @with_presets([MINIMAL], reason="too slow") def test_light_client_sync(spec, state): @@ -523,7 +512,7 @@ def test_light_client_sync(spec, state): yield from finish_test(test) -@with_altair_and_later +@with_light_client @spec_state_test_with_matching_config @with_presets([MINIMAL], reason="too slow") def test_supply_sync_committee_from_past_update(spec, state): @@ -553,7 +542,7 @@ def test_supply_sync_committee_from_past_update(spec, state): yield from finish_test(test) -@with_altair_and_later +@with_light_client @spec_state_test_with_matching_config @with_presets([MINIMAL], reason="too slow") def test_advance_finality_without_sync_committee(spec, state): diff --git a/tests/core/pyspec/eth2spec/test/altair/light_client/test_update_ranking.py b/tests/core/pyspec/eth2spec/test/altair/light_client/test_update_ranking.py index 75f1a568ad..5bca370ab5 100644 --- a/tests/core/pyspec/eth2spec/test/altair/light_client/test_update_ranking.py +++ b/tests/core/pyspec/eth2spec/test/altair/light_client/test_update_ranking.py @@ -1,7 +1,7 @@ from eth2spec.test.context import ( spec_state_test, with_presets, - with_altair_and_later, + with_light_client, ) from eth2spec.test.helpers.attestations import ( next_slots_with_attestations, @@ -29,7 +29,7 @@ def create_test_update(spec, test, with_next, with_finality, participation_rate) ) -@with_altair_and_later +@with_light_client @spec_state_test @with_presets([MINIMAL], reason="too slow") def test_update_ranking(spec, state): diff --git a/tests/core/pyspec/eth2spec/test/altair/unittests/light_client/test_sync_protocol.py b/tests/core/pyspec/eth2spec/test/altair/unittests/light_client/test_sync_protocol.py index 235f9a8b1a..a7fc7d9284 100644 --- a/tests/core/pyspec/eth2spec/test/altair/unittests/light_client/test_sync_protocol.py +++ b/tests/core/pyspec/eth2spec/test/altair/unittests/light_client/test_sync_protocol.py @@ -3,7 +3,7 @@ from eth2spec.test.context import ( spec_state_test_with_matching_config, with_presets, - with_altair_and_later, + with_light_client, ) from eth2spec.test.helpers.attestations import ( next_epoch_with_attestations, @@ -29,7 +29,7 @@ def setup_test(spec, state): return (trusted_block, store) -@with_altair_and_later +@with_light_client @spec_state_test_with_matching_config def test_process_light_client_update_not_timeout(spec, state): genesis_block, store = setup_test(spec, state) @@ -61,7 +61,7 @@ def test_process_light_client_update_not_timeout(spec, state): assert store.current_max_active_participants > 0 -@with_altair_and_later +@with_light_client @spec_state_test_with_matching_config @with_presets([MINIMAL], reason="too slow") def test_process_light_client_update_at_period_boundary(spec, state): @@ -96,7 +96,7 @@ def test_process_light_client_update_at_period_boundary(spec, state): assert store.current_max_active_participants > 0 -@with_altair_and_later +@with_light_client @spec_state_test_with_matching_config @with_presets([MINIMAL], reason="too slow") def test_process_light_client_update_timeout(spec, state): @@ -131,7 +131,7 @@ def test_process_light_client_update_timeout(spec, state): assert store.current_max_active_participants > 0 -@with_altair_and_later +@with_light_client @spec_state_test_with_matching_config @with_presets([MINIMAL], reason="too slow") def test_process_light_client_update_finality_updated(spec, state): diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index 626ffc1dbc..00589c8721 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -18,6 +18,7 @@ MINIMAL, MAINNET, ALL_PHASES, ALL_FORK_UPGRADES, + LIGHT_CLIENT_TESTING_FORKS, ) from .helpers.forks import is_post_fork from .helpers.typing import SpecForkName, PresetBaseName @@ -428,13 +429,6 @@ def decorator(fn): return decorator -with_altair_and_later = with_all_phases_from(ALTAIR) -with_bellatrix_and_later = with_all_phases_from(BELLATRIX) -with_capella_and_later = with_all_phases_from(CAPELLA) -with_deneb_and_later = with_all_phases_from(DENEB) -with_eip6110_and_later = with_all_phases_from(EIP6110) - - def _get_preset_targets(kw): preset_name = DEFAULT_TEST_PRESET if 'preset' in kw: @@ -540,6 +534,14 @@ def wrapper(*args, spec: Spec, **kw): return decorator +with_altair_and_later = with_all_phases_from(ALTAIR) +with_bellatrix_and_later = with_all_phases_from(BELLATRIX) +with_capella_and_later = with_all_phases_from(CAPELLA) +with_deneb_and_later = with_all_phases_from(DENEB) +with_eip6110_and_later = with_all_phases_from(EIP6110) +with_light_client = with_phases(LIGHT_CLIENT_TESTING_FORKS) + + class quoted_str(str): pass diff --git a/tests/core/pyspec/eth2spec/test/deneb/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/deneb/sanity/test_blocks.py index ba0797a048..2af330efba 100644 --- a/tests/core/pyspec/eth2spec/test/deneb/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/deneb/sanity/test_blocks.py @@ -16,13 +16,14 @@ ) -def run_block_with_blobs(spec, state, blob_count, excess_data_gas=1, valid=True): +def run_block_with_blobs(spec, state, blob_count, data_gas_used=1, excess_data_gas=1, valid=True): yield 'pre', state block = build_empty_block_for_next_slot(spec, state) opaque_tx, _, blob_kzg_commitments, _ = get_sample_opaque_tx(spec, blob_count=blob_count) block.body.blob_kzg_commitments = blob_kzg_commitments block.body.execution_payload.transactions = [opaque_tx] + block.body.execution_payload.data_gas_used = data_gas_used block.body.execution_payload.excess_data_gas = excess_data_gas block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload) diff --git a/tests/core/pyspec/eth2spec/test/deneb/unittests/fork_choice/__init__.py b/tests/core/pyspec/eth2spec/test/deneb/unittests/fork_choice/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/core/pyspec/eth2spec/test/deneb/unittests/fork_choice/test_validate_blobs.py b/tests/core/pyspec/eth2spec/test/deneb/unittests/fork_choice/test_validate_blobs.py deleted file mode 100644 index 0d7bd53e52..0000000000 --- a/tests/core/pyspec/eth2spec/test/deneb/unittests/fork_choice/test_validate_blobs.py +++ /dev/null @@ -1,54 +0,0 @@ -from eth2spec.test.helpers.state import ( - state_transition_and_sign_block, -) -from eth2spec.test.helpers.block import ( - build_empty_block_for_next_slot -) -from eth2spec.test.context import ( - spec_state_test, - with_deneb_and_later, -) -from eth2spec.test.helpers.execution_payload import ( - compute_el_block_hash, -) -from eth2spec.test.helpers.sharding import ( - get_sample_opaque_tx, -) - - -def _run_validate_blobs(spec, state, blob_count): - block = build_empty_block_for_next_slot(spec, state) - opaque_tx, blobs, blob_kzg_commitments, kzg_proofs = get_sample_opaque_tx(spec, blob_count=blob_count) - block.body.blob_kzg_commitments = blob_kzg_commitments - block.body.execution_payload.transactions = [opaque_tx] - block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload) - state_transition_and_sign_block(spec, state, block) - - blob_sidecars = spec.get_blob_sidecars(block, blobs, kzg_proofs) - blobs = [sidecar.blob for sidecar in blob_sidecars] - kzg_proofs = [sidecar.kzg_proof for sidecar in blob_sidecars] - spec.validate_blobs(blob_kzg_commitments, blobs, kzg_proofs) - - -@with_deneb_and_later -@spec_state_test -def test_validate_blobs_zero_blobs(spec, state): - _run_validate_blobs(spec, state, blob_count=0) - - -@with_deneb_and_later -@spec_state_test -def test_validate_blobs_one_blob(spec, state): - _run_validate_blobs(spec, state, blob_count=1) - - -@with_deneb_and_later -@spec_state_test -def test_validate_blobs_two_blobs(spec, state): - _run_validate_blobs(spec, state, blob_count=2) - - -@with_deneb_and_later -@spec_state_test -def test_validate_blobs_max_blobs(spec, state): - _run_validate_blobs(spec, state, blob_count=spec.MAX_BLOBS_PER_BLOCK) diff --git a/tests/core/pyspec/eth2spec/test/helpers/constants.py b/tests/core/pyspec/eth2spec/test/helpers/constants.py index 2140c96e45..601650e97f 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/constants.py +++ b/tests/core/pyspec/eth2spec/test/helpers/constants.py @@ -4,6 +4,7 @@ # # SpecForkName # + # Some of the Spec module functionality is exposed here to deal with phase-specific changes. PHASE0 = SpecForkName('phase0') ALTAIR = SpecForkName('altair') @@ -17,15 +18,25 @@ DAS = SpecForkName('das') EIP6110 = SpecForkName('eip6110') +# +# SpecFork settings +# + +# The forks that are deployed on Mainnet +MAINNET_FORKS = (PHASE0, ALTAIR, BELLATRIX, CAPELLA) +LATEST_FORK = MAINNET_FORKS[-1] # The forks that pytest can run with. ALL_PHASES = ( # Formal forks - PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, - # Experimental patches + *MAINNET_FORKS, + DENEB, + # Experimental features EIP6110, ) +# The forks that have light client specs +LIGHT_CLIENT_TESTING_FORKS = (*[item for item in MAINNET_FORKS if item != PHASE0], DENEB) # The forks that output to the test vectors. -TESTGEN_FORKS = (PHASE0, ALTAIR, BELLATRIX, CAPELLA, DENEB, EIP6110) +TESTGEN_FORKS = (*MAINNET_FORKS, DENEB, EIP6110) ALL_FORK_UPGRADES = { # pre_fork_name: post_fork_name @@ -46,7 +57,7 @@ AFTER_DENEB_PRE_POST_FORKS = AFTER_DENEB_UPGRADES.items() # -# Config +# Config and Preset # MAINNET = PresetBaseName('mainnet') MINIMAL = PresetBaseName('minimal') diff --git a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py index 747d678efa..b08b1975eb 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py @@ -31,6 +31,7 @@ def get_execution_payload_header(spec, execution_payload): if is_post_capella(spec): payload_header.withdrawals_root = spec.hash_tree_root(execution_payload.withdrawals) if is_post_deneb(spec): + payload_header.data_gas_used = execution_payload.data_gas_used payload_header.excess_data_gas = execution_payload.excess_data_gas if is_post_eip6110(spec): payload_header.deposit_receipts_root = spec.hash_tree_root(execution_payload.deposit_receipts) @@ -98,6 +99,7 @@ def compute_el_header_block_hash(spec, execution_payload_header_rlp.append((Binary(32, 32), withdrawals_trie_root)) if is_post_deneb(spec): # excess_data_gas + execution_payload_header_rlp.append((big_endian_int, payload_header.data_gas_used)) execution_payload_header_rlp.append((big_endian_int, payload_header.excess_data_gas)) if is_post_eip6110(spec): # deposit_receipts_root @@ -201,6 +203,7 @@ def build_empty_execution_payload(spec, state, randao_mix=None): if is_post_capella(spec): payload.withdrawals = spec.get_expected_withdrawals(state) if is_post_deneb(spec): + payload.data_gas_used = 0 payload.excess_data_gas = 0 if is_post_eip6110(spec): # just to be clear diff --git a/tests/generators/light_client/main.py b/tests/generators/light_client/main.py index c6b0e01b9b..cfe34aee4b 100644 --- a/tests/generators/light_client/main.py +++ b/tests/generators/light_client/main.py @@ -1,4 +1,4 @@ -from eth2spec.test.helpers.constants import ALTAIR, BELLATRIX, CAPELLA, DENEB, EIP6110 +from eth2spec.test.helpers.constants import ALTAIR, BELLATRIX, CAPELLA, DENEB from eth2spec.gen_helpers.gen_from_tests.gen import combine_mods, run_state_test_generators @@ -15,14 +15,12 @@ ]} capella_mods = combine_mods(_new_capella_mods, bellatrix_mods) deneb_mods = capella_mods - eip6110_mods = deneb_mods all_mods = { ALTAIR: altair_mods, BELLATRIX: bellatrix_mods, CAPELLA: capella_mods, DENEB: deneb_mods, - EIP6110: eip6110_mods, } run_state_test_generators(runner_name="light_client", all_mods=all_mods)