Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-7732: Refactor Beacon chain state transition function #3898

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 51 additions & 47 deletions specs/_features/eip7732/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@
- [Modified `process_operations`](#modified-process_operations)
- [Payload Attestations](#payload-attestations)
- [`process_payload_attestation`](#process_payload_attestation)
- [Modified `process_execution_payload`](#modified-process_execution_payload)
- [New `verify_execution_payload_envelope_signature`](#new-verify_execution_payload_envelope_signature)
- [Modified `is_merge_transition_complete`](#modified-is_merge_transition_complete)
- [Modified `validate_merge_block`](#modified-validate_merge_block)
- [Execution payload processing](#execution-payload-processing)
- [New `verify_execution_payload_envelope_signature`](#new-verify_execution_payload_envelope_signature)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  - [New `verify_execution_payload_envelope_signature`](#new-verify_execution_payload_envelope_signature)

- [New `process_execution_payload`](#new-process_execution_payload)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
Expand Down Expand Up @@ -427,7 +428,8 @@ The post-state corresponding to a pre-state `state` and a signed execution paylo
def process_block(state: BeaconState, block: BeaconBlock) -> None:
process_block_header(state, block)
process_withdrawals(state) # [Modified in EIP-7732]
process_execution_payload_header(state, block) # [Modified in EIP-7732, removed process_execution_payload]
# Removed `process_execution_payload` in EIP-7732
process_execution_payload_header(state, block) # [New in EIP-7732]
process_randao(state, block.body)
process_eth1_data(state, block.body)
process_operations(state, block.body) # [Modified in EIP-7732]
Expand Down Expand Up @@ -592,9 +594,51 @@ def process_payload_attestation(state: BeaconState, payload_attestation: Payload
increase_balance(state, proposer_index, proposer_reward)
```

#### Modified `process_execution_payload`
#### Modified `is_merge_transition_complete`

`is_merge_transition_complete` is modified only for testing purposes to add the blob kzg commitments root for an empty list

```python
def is_merge_transition_complete(state: BeaconState) -> bool:
header = ExecutionPayloadHeader()
kzgs = List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]()
header.blob_kzg_commitments_root = kzgs.hash_tree_root()

return state.latest_execution_payload_header != header
```

##### New `verify_execution_payload_envelope_signature`
#### Modified `validate_merge_block`
`validate_merge_block` is modified to use the new `signed_execution_payload_header` message in the Beacon Block Body

```python
def validate_merge_block(block: BeaconBlock) -> None:
"""
Check the parent PoW block of execution payload is a valid terminal PoW block.

Note: Unavailable PoW block(s) may later become available,
and a client software MAY delay a call to ``validate_merge_block``
until the PoW block(s) become available.
"""
if TERMINAL_BLOCK_HASH != Hash32():
# If `TERMINAL_BLOCK_HASH` is used as an override, the activation epoch must be reached.
assert compute_epoch_at_slot(block.slot) >= TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH
assert block.body.signed_execution_payload_header.message.parent_block_hash == TERMINAL_BLOCK_HASH
return

# Modified in EIP-7732
pow_block = get_pow_block(block.body.signed_execution_payload_header.message.parent_block_hash)
# Check if `pow_block` is available
assert pow_block is not None
pow_parent = get_pow_block(pow_block.parent_hash)
# Check if `pow_parent` is available
assert pow_parent is not None
# Check if `pow_block` is a valid terminal PoW block
assert is_valid_terminal_pow_block(pow_block, pow_parent)
```

### Execution payload processing

#### New `verify_execution_payload_envelope_signature`

```python
def verify_execution_payload_envelope_signature(
Expand All @@ -604,6 +648,8 @@ def verify_execution_payload_envelope_signature(
return bls.Verify(builder.pubkey, signing_root, signed_envelope.signature)
```

#### New `process_execution_payload`

*Note*: `process_execution_payload` is now an independent check in state transition. It is called when importing a signed execution payload proposed by the builder of the current slot.

```python
Expand Down Expand Up @@ -672,45 +718,3 @@ def process_execution_payload(state: BeaconState,
if verify:
assert envelope.state_root == hash_tree_root(state)
```

#### Modified `is_merge_transition_complete`

`is_merge_transition_complete` is modified only for testing purposes to add the blob kzg commitments root for an empty list

```python
def is_merge_transition_complete(state: BeaconState) -> bool:
header = ExecutionPayloadHeader()
kzgs = List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]()
header.blob_kzg_commitments_root = kzgs.hash_tree_root()

return state.latest_execution_payload_header != header
```

#### Modified `validate_merge_block`
`validate_merge_block` is modified to use the new `signed_execution_payload_header` message in the Beacon Block Body

```python
def validate_merge_block(block: BeaconBlock) -> None:
"""
Check the parent PoW block of execution payload is a valid terminal PoW block.

Note: Unavailable PoW block(s) may later become available,
and a client software MAY delay a call to ``validate_merge_block``
until the PoW block(s) become available.
"""
if TERMINAL_BLOCK_HASH != Hash32():
# If `TERMINAL_BLOCK_HASH` is used as an override, the activation epoch must be reached.
assert compute_epoch_at_slot(block.slot) >= TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH
assert block.body.signed_execution_payload_header.message.parent_block_hash == TERMINAL_BLOCK_HASH
return

# Modified in EIP-7732
pow_block = get_pow_block(block.body.signed_execution_payload_header.message.parent_block_hash)
# Check if `pow_block` is available
assert pow_block is not None
pow_parent = get_pow_block(pow_block.parent_hash)
# Check if `pow_parent` is available
assert pow_parent is not None
# Check if `pow_block` is a valid terminal PoW block
assert is_valid_terminal_pow_block(pow_block, pow_parent)
```