define execution engine protocol
This commit is contained in:
parent
e78e045847
commit
f58ba8f5b2
|
@ -22,6 +22,9 @@
|
|||
- [New containers](#new-containers)
|
||||
- [`ExecutionPayload`](#executionpayload)
|
||||
- [`ExecutionPayloadHeader`](#executionpayloadheader)
|
||||
- [Protocols](#protocols)
|
||||
- [`ExecutionEngine`](#executionengine)
|
||||
- [`new_block`](#new_block)
|
||||
- [Helper functions](#helper-functions)
|
||||
- [Misc](#misc)
|
||||
- [`is_execution_enabled`](#is_execution_enabled)
|
||||
|
@ -30,7 +33,6 @@
|
|||
- [`compute_time_at_slot`](#compute_time_at_slot)
|
||||
- [Block processing](#block-processing)
|
||||
- [Execution payload processing](#execution-payload-processing)
|
||||
- [`verify_execution_state_transition`](#verify_execution_state_transition)
|
||||
- [`process_execution_payload`](#process_execution_payload)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
@ -137,6 +139,30 @@ class ExecutionPayloadHeader(Container):
|
|||
transactions_root: Root
|
||||
```
|
||||
|
||||
## Protocols
|
||||
|
||||
### `ExecutionEngine`
|
||||
|
||||
The `ExecutionEngine` protocol separates the consensus and execution sub-systems.
|
||||
The consensus implementation references an instance of this sub-system with `EXECUTION_ENGINE`.
|
||||
|
||||
The following methods are added to the `ExecutionEngine` protocol for use in the state transition:
|
||||
|
||||
#### `new_block`
|
||||
|
||||
Verifies the given `ExecutionPayload` with respect to execution state transition, and persists changes if valid.
|
||||
|
||||
The body of this function is implementation dependent.
|
||||
The Consensus API may be used to implement this with an external execution engine.
|
||||
|
||||
```python
|
||||
def new_block(self: ExecutionEngine, execution_payload: ExecutionPayload) -> bool:
|
||||
"""
|
||||
Returns True if the ``execution_payload`` was verified and processed successfully, False otherwise.
|
||||
"""
|
||||
...
|
||||
```
|
||||
|
||||
## Helper functions
|
||||
|
||||
### Misc
|
||||
|
@ -182,20 +208,15 @@ def process_block(state: BeaconState, block: BeaconBlock) -> None:
|
|||
process_operations(state, block.body)
|
||||
# Pre-merge, skip execution payload processing
|
||||
if is_execution_enabled(state, block):
|
||||
process_execution_payload(state, block.body.execution_payload) # [New in Merge]
|
||||
process_execution_payload(state, block.body.execution_payload, EXECUTION_ENGINE) # [New in Merge]
|
||||
```
|
||||
|
||||
#### Execution payload processing
|
||||
|
||||
##### `verify_execution_state_transition`
|
||||
|
||||
Let `verify_execution_state_transition(execution_payload: ExecutionPayload) -> bool` be the function that verifies given `ExecutionPayload` with respect to execution state transition.
|
||||
The body of the function is implementation dependent.
|
||||
|
||||
##### `process_execution_payload`
|
||||
|
||||
```python
|
||||
def process_execution_payload(state: BeaconState, execution_payload: ExecutionPayload) -> None:
|
||||
def process_execution_payload(state: BeaconState, execution_payload: ExecutionPayload, execution_engine: ExecutionEngine) -> None:
|
||||
"""
|
||||
Note: This function is designed to be able to be run in parallel with the other `process_block` sub-functions
|
||||
"""
|
||||
|
@ -205,7 +226,7 @@ def process_execution_payload(state: BeaconState, execution_payload: ExecutionPa
|
|||
|
||||
assert execution_payload.timestamp == compute_time_at_slot(state, state.slot)
|
||||
|
||||
assert verify_execution_state_transition(execution_payload)
|
||||
assert execution_engine.new_block(execution_payload)
|
||||
|
||||
state.latest_execution_payload_header = ExecutionPayloadHeader(
|
||||
block_hash=execution_payload.block_hash,
|
||||
|
|
|
@ -8,11 +8,16 @@
|
|||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Helpers](#helpers)
|
||||
- [Protocols](#protocols)
|
||||
- [`ExecutionEngine`](#executionengine)
|
||||
- [`set_head`](#set_head)
|
||||
- [`finalize_block`](#finalize_block)
|
||||
- [Containers](#containers)
|
||||
- [`PowBlock`](#powblock)
|
||||
- [Helper functions](#helper-functions)
|
||||
- [`get_pow_block`](#get_pow_block)
|
||||
- [`is_valid_transition_block`](#is_valid_transition_block)
|
||||
- [Updated fork-choice handlers](#updated-fork-choice-handlers)
|
||||
- [Updated fork-choice handlers](#updated-fork-choice-handlers)
|
||||
- [`on_block`](#on_block)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
@ -24,7 +29,44 @@ This is the modification of the fork choice according to the executable beacon c
|
|||
|
||||
*Note*: It introduces the process of transition from the last PoW block to the first PoS block.
|
||||
|
||||
### Helpers
|
||||
## Protocols
|
||||
|
||||
### `ExecutionEngine`
|
||||
|
||||
The following methods are added to the `ExecutionEngine` protocol for use in the fork choice:
|
||||
|
||||
#### `set_head`
|
||||
|
||||
Re-organizes the execution payload chain and corresponding state to make `block_hash` the head.
|
||||
|
||||
The body of this function is implementation dependent.
|
||||
The Consensus API may be used to implement this with an external execution engine.
|
||||
|
||||
```python
|
||||
def set_head(self: ExecutionEngine, block_hash: Hash32) -> bool:
|
||||
"""
|
||||
Returns True if the ``block_hash`` was successfully set as head of the execution payload chain.
|
||||
"""
|
||||
...
|
||||
```
|
||||
|
||||
#### `finalize_block`
|
||||
|
||||
Applies finality to the execution state: it irreversibly persists the chain of all execution payloads
|
||||
and corresponding state, up to and including `block_hash`.
|
||||
|
||||
The body of this function is implementation dependent.
|
||||
The Consensus API may be used to implement this with an external execution engine.
|
||||
|
||||
```python
|
||||
def finalize_block(self: ExecutionEngine, block_hash: Hash32) -> bool:
|
||||
"""
|
||||
Returns True if the data up to and including ``block_hash`` was successfully finalized.
|
||||
"""
|
||||
...
|
||||
```
|
||||
|
||||
## Containers
|
||||
|
||||
#### `PowBlock`
|
||||
|
||||
|
@ -36,6 +78,8 @@ class PowBlock(Container):
|
|||
total_difficulty: uint256
|
||||
```
|
||||
|
||||
## Helper functions
|
||||
|
||||
#### `get_pow_block`
|
||||
|
||||
Let `get_pow_block(block_hash: Hash32) -> PowBlock` be the function that given the hash of the PoW block returns its data.
|
||||
|
@ -52,7 +96,7 @@ def is_valid_transition_block(block: PowBlock) -> bool:
|
|||
return block.is_valid and is_total_difficulty_reached
|
||||
```
|
||||
|
||||
### Updated fork-choice handlers
|
||||
## Updated fork-choice handlers
|
||||
|
||||
#### `on_block`
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Protocols](#protocols)
|
||||
- [`ExecutionEngine`](#executionengine)
|
||||
- [`assemble_block`](#assemble_block)
|
||||
- [Beacon chain responsibilities](#beacon-chain-responsibilities)
|
||||
- [Block proposal](#block-proposal)
|
||||
- [Constructing the `BeaconBlockBody`](#constructing-the-beaconblockbody)
|
||||
|
@ -32,6 +35,25 @@ This document is an extension of the [Phase 0 -- Validator](../phase0/validator.
|
|||
|
||||
All terminology, constants, functions, and protocol mechanics defined in the updated Beacon Chain doc of [The Merge](./beacon-chain.md) are requisite for this document and used throughout. Please see related Beacon Chain doc before continuing and use them as a reference throughout.
|
||||
|
||||
## Protocols
|
||||
|
||||
### `ExecutionEngine`
|
||||
|
||||
The following methods are added to the `ExecutionEngine` protocol for use as a validator:
|
||||
|
||||
#### `assemble_block`
|
||||
|
||||
Produces a new instance of an execution payload, with the specified timestamp,
|
||||
on top of the execution payload chain tip identified by `block_head`.
|
||||
|
||||
The body of this function is implementation dependent.
|
||||
The Consensus API may be used to implement this with an external execution engine.
|
||||
|
||||
```python
|
||||
def assemble_block(self: ExecutionEngine, block_hash: Hash32, timestamp: uint64) -> ExecutionPayload:
|
||||
...
|
||||
```
|
||||
|
||||
## Beacon chain responsibilities
|
||||
|
||||
All validator responsibilities remain unchanged other than those noted below. Namely, the transition block handling and the addition of `ExecutionPayload`.
|
||||
|
@ -49,12 +71,12 @@ Let `get_pow_chain_head() -> PowBlock` be the function that returns the head of
|
|||
###### `produce_execution_payload`
|
||||
|
||||
Let `produce_execution_payload(parent_hash: Hash32, timestamp: uint64) -> ExecutionPayload` be the function that produces new instance of execution payload.
|
||||
The body of this function is implementation dependent.
|
||||
The `ExecutionEngine` protocol is used for the implementation specific part of execution payload proposals.
|
||||
|
||||
* Set `block.body.execution_payload = get_execution_payload(state)` where:
|
||||
|
||||
```python
|
||||
def get_execution_payload(state: BeaconState) -> ExecutionPayload:
|
||||
def get_execution_payload(state: BeaconState, execution_engine: ExecutionEngine) -> ExecutionPayload:
|
||||
if not is_transition_completed(state):
|
||||
pow_block = get_pow_chain_head()
|
||||
if not is_valid_transition_block(pow_block):
|
||||
|
@ -63,7 +85,7 @@ def get_execution_payload(state: BeaconState) -> ExecutionPayload:
|
|||
else:
|
||||
# Signify merge via producing on top of the last PoW block
|
||||
timestamp = compute_time_at_slot(state, state.slot)
|
||||
return produce_execution_payload(pow_block.block_hash, timestamp)
|
||||
return execution_engine.assemble_block(pow_block.block_hash, timestamp)
|
||||
|
||||
# Post-merge, normal payload
|
||||
execution_parent_hash = state.latest_execution_payload_header.block_hash
|
||||
|
|
Loading…
Reference in New Issue