2021-03-11 12:33:36 +00:00
# Ethereum 2.0 The Merge
2021-03-24 10:30:29 +00:00
**Warning:** This document is currently based on [Phase 0 ](../phase0/beacon-chain.md ) but will be rebased to [Altair ](../altair/beacon-chain.md ) once the latter is shipped.
2021-03-17 16:39:35 +00:00
2021-03-11 12:33:36 +00:00
**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 )
2021-03-29 18:56:43 +00:00
- [Custom types ](#custom-types )
2021-03-11 12:33:36 +00:00
- [Constants ](#constants )
- [Execution ](#execution )
2021-05-05 13:35:36 +00:00
- [Configuration ](#configuration )
2021-03-11 12:33:36 +00:00
- [Containers ](#containers )
- [Extended containers ](#extended-containers )
- [`BeaconBlockBody` ](#beaconblockbody )
- [`BeaconState` ](#beaconstate )
- [New containers ](#new-containers )
2021-04-08 08:29:05 +00:00
- [`ExecutionPayload` ](#executionpayload )
- [`ExecutionPayloadHeader` ](#executionpayloadheader )
2021-05-10 13:48:37 +00:00
- [Protocols ](#protocols )
- [`ExecutionEngine` ](#executionengine )
- [`new_block` ](#new_block )
2021-03-11 12:33:36 +00:00
- [Helper functions ](#helper-functions )
- [Misc ](#misc )
2021-05-06 00:21:52 +00:00
- [`is_execution_enabled` ](#is_execution_enabled )
2021-03-20 13:21:11 +00:00
- [`is_transition_completed` ](#is_transition_completed )
- [`is_transition_block` ](#is_transition_block )
2021-04-08 09:26:32 +00:00
- [`compute_time_at_slot` ](#compute_time_at_slot )
2021-03-11 12:33:36 +00:00
- [Block processing ](#block-processing )
2021-04-08 08:29:05 +00:00
- [Execution payload processing ](#execution-payload-processing )
- [`process_execution_payload` ](#process_execution_payload )
2021-03-11 12:33:36 +00:00
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
## Introduction
2021-03-24 10:30:29 +00:00
This is a patch implementing the executable beacon chain proposal.
2021-04-08 08:29:05 +00:00
It enshrines transaction execution and validity as a first class citizen at the core of the beacon chain.
2021-03-11 12:33:36 +00:00
2021-03-26 19:20:23 +00:00
## Custom types
We define the following Python custom types for type hinting and readability:
| Name | SSZ equivalent | Description |
| - | - | - |
| `OpaqueTransaction` | `ByteList[MAX_BYTES_PER_OPAQUE_TRANSACTION]` | a byte-list containing a single [typed transaction envelope ](https://eips.ethereum.org/EIPS/eip-2718#opaque-byte-array-rather-than-an-rlp-array ) structured as `TransactionType \|\| TransactionPayload` |
2021-03-11 12:33:36 +00:00
## Constants
### Execution
| Name | Value |
| - | - |
2021-03-26 19:20:23 +00:00
| `MAX_BYTES_PER_OPAQUE_TRANSACTION` | `uint64(2**20)` (= 1,048,576) |
2021-04-19 05:24:06 +00:00
| `MAX_EXECUTION_TRANSACTIONS` | `uint64(2**14)` (= 16,384) |
2021-03-24 10:30:29 +00:00
| `BYTES_PER_LOGS_BLOOM` | `uint64(2**8)` (= 256) |
2021-03-11 12:33:36 +00:00
2021-05-05 13:35:36 +00:00
## Configuration
Warning: this configuration is not definitive.
| Name | Value |
| - | - |
| `MERGE_FORK_VERSION` | `Version('0x02000000')` |
| `MERGE_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
| `TRANSITION_TOTAL_DIFFICULTY` | **TBD** |
2021-03-11 12:33:36 +00:00
## Containers
### Extended containers
*Note*: Extended SSZ containers inherit all fields from the parent in the original
order and append any additional fields to the end.
#### `BeaconBlockBody`
2021-04-08 08:29:05 +00:00
*Note*: `BeaconBlockBody` fields remain unchanged other than the addition of `execution_payload` .
2021-03-11 12:33:36 +00:00
```python
class BeaconBlockBody(phase0.BeaconBlockBody):
2021-04-08 08:29:05 +00:00
execution_payload: ExecutionPayload # [New in Merge]
2021-03-11 12:33:36 +00:00
```
#### `BeaconState`
2021-04-08 08:29:05 +00:00
*Note*: `BeaconState` fields remain unchanged other than addition of `latest_execution_payload_header` .
2021-03-11 12:33:36 +00:00
```python
2021-03-22 15:14:31 +00:00
class BeaconState(phase0.BeaconState):
2021-04-08 08:29:05 +00:00
# Execution-layer
latest_execution_payload_header: ExecutionPayloadHeader # [New in Merge]
2021-03-11 12:33:36 +00:00
```
### New containers
2021-04-08 08:29:05 +00:00
#### `ExecutionPayload`
2021-03-11 12:33:36 +00:00
2021-04-08 08:29:05 +00:00
The execution payload included in a `BeaconBlockBody` .
2021-03-11 12:33:36 +00:00
```python
2021-04-08 08:29:05 +00:00
class ExecutionPayload(Container):
2021-04-08 08:48:03 +00:00
block_hash: Hash32 # Hash of execution block
parent_hash: Hash32
2021-03-11 12:33:36 +00:00
coinbase: Bytes20
state_root: Bytes32
2021-03-31 09:35:55 +00:00
number: uint64
2021-03-11 12:33:36 +00:00
gas_limit: uint64
gas_used: uint64
2021-04-13 13:08:47 +00:00
timestamp: uint64
2021-03-11 12:33:36 +00:00
receipt_root: Bytes32
2021-03-25 12:41:00 +00:00
logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM]
2021-04-19 05:24:06 +00:00
transactions: List[OpaqueTransaction, MAX_EXECUTION_TRANSACTIONS]
2021-03-11 12:33:36 +00:00
```
2021-04-08 08:29:05 +00:00
#### `ExecutionPayloadHeader`
2021-04-02 14:48:02 +00:00
2021-04-08 08:29:05 +00:00
The execution payload header included in a `BeaconState` .
2021-04-02 14:48:02 +00:00
2021-04-08 08:29:05 +00:00
*Note:* Holds execution payload data without transaction bodies.
2021-04-02 14:48:02 +00:00
```python
2021-04-08 08:29:05 +00:00
class ExecutionPayloadHeader(Container):
2021-04-08 08:48:03 +00:00
block_hash: Hash32 # Hash of execution block
parent_hash: Hash32
2021-04-02 14:48:02 +00:00
coinbase: Bytes20
state_root: Bytes32
number: uint64
gas_limit: uint64
gas_used: uint64
2021-04-13 13:08:47 +00:00
timestamp: uint64
2021-04-02 14:48:02 +00:00
receipt_root: Bytes32
logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM]
2021-04-06 05:48:33 +00:00
transactions_root: Root
2021-04-02 14:48:02 +00:00
```
2021-05-10 13:48:37 +00:00
## 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.
"""
...
```
2021-03-11 12:33:36 +00:00
## Helper functions
### Misc
2021-05-06 00:21:52 +00:00
#### `is_execution_enabled`
```python
def is_execution_enabled(state: BeaconState, block: BeaconBlock) -> bool:
return is_transition_completed(state) or is_transition_block(state, block)
```
2021-03-20 13:21:11 +00:00
#### `is_transition_completed`
2021-03-11 12:33:36 +00:00
```python
2021-04-14 06:54:49 +00:00
def is_transition_completed(state: BeaconState) -> bool:
2021-04-08 14:14:01 +00:00
return state.latest_execution_payload_header != ExecutionPayloadHeader()
2021-03-11 12:33:36 +00:00
```
2021-03-20 13:21:11 +00:00
#### `is_transition_block`
2021-03-11 12:33:36 +00:00
```python
2021-05-04 22:17:10 +00:00
def is_transition_block(state: BeaconState, block: BeaconBlock) -> bool:
return not is_transition_completed(state) and block.body.execution_payload != ExecutionPayload()
2021-03-11 12:33:36 +00:00
```
2021-04-08 09:26:32 +00:00
#### `compute_time_at_slot`
2021-04-14 06:53:30 +00:00
*Note*: This function is unsafe with respect to overflows and underflows.
2021-04-08 09:26:32 +00:00
```python
def compute_time_at_slot(state: BeaconState, slot: Slot) -> uint64:
slots_since_genesis = slot - GENESIS_SLOT
return uint64(state.genesis_time + slots_since_genesis * SECONDS_PER_SLOT)
```
2021-03-11 12:33:36 +00:00
### Block processing
```python
def process_block(state: BeaconState, block: BeaconBlock) -> None:
process_block_header(state, block)
process_randao(state, block.body)
2021-03-20 13:21:11 +00:00
process_eth1_data(state, block.body)
2021-03-11 12:33:36 +00:00
process_operations(state, block.body)
2021-05-04 22:17:10 +00:00
# Pre-merge, skip execution payload processing
2021-05-06 00:21:52 +00:00
if is_execution_enabled(state, block):
2021-05-10 13:48:37 +00:00
process_execution_payload(state, block.body.execution_payload, EXECUTION_ENGINE) # [New in Merge]
2021-03-11 12:33:36 +00:00
```
2021-04-08 08:29:05 +00:00
#### Execution payload processing
2021-03-11 12:33:36 +00:00
2021-04-08 08:29:05 +00:00
##### `process_execution_payload`
2021-03-11 12:33:36 +00:00
```python
2021-05-12 00:40:23 +00:00
def process_execution_payload(state: BeaconState,
execution_payload: ExecutionPayload,
execution_engine: ExecutionEngine) -> None:
2021-03-11 12:33:36 +00:00
"""
2021-03-24 10:30:29 +00:00
Note: This function is designed to be able to be run in parallel with the other `process_block` sub-functions
2021-03-11 12:33:36 +00:00
"""
2021-04-08 14:14:34 +00:00
if is_transition_completed(state):
2021-04-08 14:14:01 +00:00
assert execution_payload.parent_hash == state.latest_execution_payload_header.block_hash
assert execution_payload.number == state.latest_execution_payload_header.number + 1
2021-04-08 08:29:05 +00:00
2021-04-13 13:08:47 +00:00
assert execution_payload.timestamp == compute_time_at_slot(state, state.slot)
2021-05-10 13:48:37 +00:00
assert execution_engine.new_block(execution_payload)
2021-04-08 08:29:05 +00:00
state.latest_execution_payload_header = ExecutionPayloadHeader(
block_hash=execution_payload.block_hash,
parent_hash=execution_payload.parent_hash,
coinbase=execution_payload.coinbase,
state_root=execution_payload.state_root,
number=execution_payload.number,
gas_limit=execution_payload.gas_limit,
gas_used=execution_payload.gas_used,
2021-04-13 13:08:47 +00:00
timestamp=execution_payload.timestamp,
2021-04-08 08:29:05 +00:00
receipt_root=execution_payload.receipt_root,
logs_bloom=execution_payload.logs_bloom,
transactions_root=hash_tree_root(execution_payload.transactions),
2021-04-02 14:48:02 +00:00
)
2021-03-11 12:33:36 +00:00
```