Fix light client tests

This commit is contained in:
Hsiao-Wei Wang 2023-05-10 22:59:39 +08:00
parent 74596190e7
commit 6e08327d1f
No known key found for this signature in database
GPG Key ID: AE3D6B174F971DE4
6 changed files with 409 additions and 6 deletions

View File

@ -1060,6 +1060,10 @@ class PySpecCommand(Command):
"""
if self.spec_fork == EIP7002:
self.md_doc_paths += """
specs/_features/eip7002/light-client/fork.md
specs/_features/eip7002/light-client/full-node.md
specs/_features/eip7002/light-client/p2p-interface.md
specs/_features/eip7002/light-client/sync-protocol.md
specs/_features/eip7002/beacon-chain.md
specs/_features/eip7002/fork.md
"""

View File

@ -32,6 +32,27 @@ Additional documents describes the impact of the upgrade on certain roles:
def get_lc_execution_root(header: LightClientHeader) -> Root:
epoch = compute_epoch_at_slot(header.beacon.slot)
if epoch >= EIP6110_FORK_EPOCH:
execution_header = 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,
deposit_receipts_root=header.execution.deposit_receipts_root,
)
return hash_tree_root(execution_header)
if epoch >= DENEB_FORK_EPOCH:
return hash_tree_root(header.execution)
@ -73,12 +94,6 @@ def is_valid_light_client_header(header: LightClientHeader) -> bool:
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,

View File

@ -0,0 +1,112 @@
# EIP-7002 Light Client -- Fork Logic
## Table of contents
<!-- TOC -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Introduction](#introduction)
- [Upgrading light client data](#upgrading-light-client-data)
- [Upgrading the store](#upgrading-the-store)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
## Introduction
This document describes how to upgrade existing light client objects based on the [Deneb specification](../../deneb/light-client/sync-protocol.md) to eip7002. This is necessary when processing pre-eip7002 data with a post-eip7002 `LightClientStore`. Note that the data being exchanged over the network protocols uses the original format.
### Upgrading light client data
A eip7002 `LightClientStore` can still process earlier light client data. In order to do so, that pre-eip7002 data needs to be locally upgraded to eip7002 before processing.
```python
def upgrade_lc_header_to_eip7002(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,
exits_root=Root(), # [New in EIP7002]
),
execution_branch=pre.execution_branch,
)
```
```python
def upgrade_lc_bootstrap_to_eip7002(pre: deneb.LightClientBootstrap) -> LightClientBootstrap:
return LightClientBootstrap(
header=upgrade_lc_header_to_eip7002(pre.header),
current_sync_committee=pre.current_sync_committee,
current_sync_committee_branch=pre.current_sync_committee_branch,
)
```
```python
def upgrade_lc_update_to_eip7002(pre: deneb.LightClientUpdate) -> LightClientUpdate:
return LightClientUpdate(
attested_header=upgrade_lc_header_to_eip7002(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_eip7002(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_eip7002(pre: deneb.LightClientFinalityUpdate) -> LightClientFinalityUpdate:
return LightClientFinalityUpdate(
attested_header=upgrade_lc_header_to_eip7002(pre.attested_header),
finalized_header=upgrade_lc_header_to_eip7002(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_eip7002(pre: deneb.LightClientOptimisticUpdate) -> LightClientOptimisticUpdate:
return LightClientOptimisticUpdate(
attested_header=upgrade_lc_header_to_eip7002(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 eip7002 before eip7002 based light client data can be processed. The `LightClientStore` upgrade MAY be performed before `EIP7002_FORK_EPOCH`.
```python
def upgrade_lc_store_to_eip7002(pre: deneb.LightClientStore) -> LightClientStore:
if pre.best_valid_update is None:
best_valid_update = None
else:
best_valid_update = upgrade_lc_update_to_eip7002(pre.best_valid_update)
return LightClientStore(
finalized_header=upgrade_lc_header_to_eip7002(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_eip7002(pre.optimistic_header),
previous_max_active_participants=pre.previous_max_active_participants,
current_max_active_participants=pre.current_max_active_participants,
)
```

View File

@ -0,0 +1,77 @@
# EIP-7002 Light Client -- Full Node
**Notice**: This document is a work-in-progress for researchers and implementers.
## Table of contents
<!-- TOC -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Introduction](#introduction)
- [Helper functions](#helper-functions)
- [Modified `block_to_light_client_header`](#modified-block_to_light_client_header)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
## Introduction
This upgrade adds information about the execution payload to light client data as part of the EIP-7002 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 EIP7002]
if epoch >= EIP7002_FORK_EPOCH:
execution_header.exits_root = hash_tree_root(payload.exits)
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,
)
```

View File

@ -0,0 +1,111 @@
# EIP-7002 Light Client -- Networking
**Notice**: This document is a work-in-progress for researchers and implementers.
## Table of contents
<!-- TOC -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [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)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
## Networking
The [Deneb light client networking specification](../../deneb/light-client/p2p-interface.md) is extended to exchange [EIP-7002 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` |
| `EIP7002_FORK_VERSION` and later | `eip7002.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` |
| `EIP7002_FORK_VERSION` and later | `eip7002.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` |
| `EIP7002_FORK_VERSION` and later | `eip7002.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` |
| `EIP7002_FORK_VERSION` and later | `eip7002.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` |
| `EIP7002_FORK_VERSION` and later | `eip7002.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` |
| `EIP7002_FORK_VERSION` and later | `eip7002.LightClientOptimisticUpdate` |

View File

@ -0,0 +1,84 @@
# EIP-7002 Light Client -- Sync Protocol
**Notice**: This document is a work-in-progress for researchers and implementers.
## Table of contents
<!-- TOC -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Introduction](#introduction)
- [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)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
## Introduction
This upgrade updates light client data to include the EIP-7002 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-7002.
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 >= EIP7002_FORK_EPOCH:
execution_header = 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,
exits_root=header.execution.exits_root,
)
return hash_tree_root(execution_header)
if epoch >= DENEB_FORK_EPOCH:
return hash_tree_root(header.execution)
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-7002]
if epoch < EIP7002_FORK_EPOCH:
if header.execution.exits_root != Root():
return False
if epoch < DENEB_FORK_EPOCH:
if header.execution.excess_data_gas != uint256(0):
return False
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,
)
```