forked from DecentralizedClimateFoundation/DCIPs
155 lines
8.2 KiB
Markdown
155 lines
8.2 KiB
Markdown
|
---
|
||
|
eip: 6466
|
||
|
title: SSZ Receipts Root
|
||
|
description: Migration of receipts MPT commitment to SSZ
|
||
|
author: Etan Kissling (@etan-status), Vitalik Buterin (@vbuterin)
|
||
|
discussions-to: https://ethereum-magicians.org/t/eip-6466-ssz-receipts-root/12884
|
||
|
status: Draft
|
||
|
type: Standards Track
|
||
|
category: Core
|
||
|
created: 2023-02-08
|
||
|
requires: 155, 658, 1559, 2718, 2930, 4844, 6404, 6475
|
||
|
---
|
||
|
|
||
|
## Abstract
|
||
|
|
||
|
This EIP defines a migration process of existing Merkle-Patricia Trie (MPT) commitments for receipts to [Simple Serialize (SSZ)](https://github.com/ethereum/consensus-specs/blob/67c2f9ee9eb562f7cc02b2ff90d92c56137944e1/ssz/simple-serialize.md)
|
||
|
|
||
|
## Motivation
|
||
|
|
||
|
While the consensus `ExecutionPayloadHeader` and the execution block header map to each other conceptually, they are encoded differently. This EIP aims to align the encoding of the `receipts_root`, taking advantage of the more modern SSZ format. This brings several advantages:
|
||
|
|
||
|
1. **Better for light clients:** Light clients no longer need to obtain and decode entire receipts to verify receipt related fields provided by the execution JSON-RPC API.
|
||
|
|
||
|
2. **Better for smart contracts:** The SSZ format is optimized for production and verification of merkle proofs. It allows proving specific fields of containers and allows chunked processing, e.g., to support handling receipts with lots of logs.
|
||
|
|
||
|
3. **Reducing complexity:** The proposed design reduces the number of use cases that require support for Merkle-Patricia Trie (MPT).
|
||
|
|
||
|
## Specification
|
||
|
|
||
|
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
|
||
|
|
||
|
### Existing definitions
|
||
|
|
||
|
Definitions from existing specifications that are used throughout this document are replicated here for reference.
|
||
|
|
||
|
| Name | SSZ equivalent |
|
||
|
| - | - |
|
||
|
| [`ExecutionAddress`](https://github.com/ethereum/consensus-specs/blob/67c2f9ee9eb562f7cc02b2ff90d92c56137944e1/specs/bellatrix/beacon-chain.md#custom-types) | `Bytes20` |
|
||
|
| [`TransactionType`](./eip-6404.md) | `uint8` |
|
||
|
|
||
|
| Name | Value |
|
||
|
| - | - |
|
||
|
| [`BYTES_PER_LOGS_BLOOM`](https://github.com/ethereum/consensus-specs/blob/67c2f9ee9eb562f7cc02b2ff90d92c56137944e1/specs/bellatrix/beacon-chain.md#execution) | `uint64(2**8)` (= 256) |
|
||
|
| [`MAX_TRANSACTIONS_PER_PAYLOAD`](https://github.com/ethereum/consensus-specs/blob/67c2f9ee9eb562f7cc02b2ff90d92c56137944e1/specs/bellatrix/beacon-chain.md#execution) | `uint64(2**20)` (= 1,048,576) |
|
||
|
|
||
|
### Normalized `Receipt` representation
|
||
|
|
||
|
A `Receipt` SSZ container is introduced to represent receipts. The definition uses the `Optional[T]` SSZ type as defined in [EIP-6475](./eip-6475.md).
|
||
|
|
||
|
| Name | SSZ equivalent |
|
||
|
| - | - |
|
||
|
| `Topic` | `Bytes32` |
|
||
|
|
||
|
| Name | Value | Notes |
|
||
|
| - | - | - |
|
||
|
| `MAX_TOPICS_PER_LOG` | `uint64(2**2)` (= 4) | `LOG0` through `LOG4` opcodes allow 0-4 topics per log |
|
||
|
| `MAX_LOG_DATA_SIZE` | `uint64(2**24)` (= 16,777,216) | Recommended devp2p soft limit for entire receipt: [2 MiB](https://github.com/ethereum/devp2p/blob/bd17dac4228c69b6379644355f373669f74952cd/caps/eth.md#receipts-0x10) |
|
||
|
| `MAX_LOGS_PER_RECEIPT` | `uint64(2**20)` (= 1,048,576) | Same scaling factor as [`MAX_TRANSACTIONS_PER_PAYLOAD`](https://github.com/ethereum/consensus-specs/blob/67c2f9ee9eb562f7cc02b2ff90d92c56137944e1/specs/bellatrix/beacon-chain.md#execution) |
|
||
|
|
||
|
```python
|
||
|
class ReceiptLog(Container):
|
||
|
address: ExecutionAddress
|
||
|
topics: List[Topic, MAX_TOPICS_PER_LOG]
|
||
|
data: ByteVector[MAX_LOG_DATA_SIZE]
|
||
|
|
||
|
class Receipt(Container):
|
||
|
status: uint256 # EIP-658
|
||
|
cumulative_gas_used: uint64
|
||
|
logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM]
|
||
|
logs: List[ReceiptLog, MAX_LOGS_PER_RECEIPT]
|
||
|
tx_type: TransactionType
|
||
|
cumulative_data_gas_used: Optional[uint64]
|
||
|
```
|
||
|
|
||
|
### Consensus `ExecutionPayload` building
|
||
|
|
||
|
When building a consensus `ExecutionPayload`, the `receipts_root` is now based on the normalized `Receipt` SSZ container. Implementations that currently produce receipts in the [EIP-2718](./eip-2718.md) format can convert them using the [`normalize_receipt`](../assets/eip-6466/helpers/convert_receipts.py) helper function.
|
||
|
|
||
|
### Consensus `ExecutionPayload` changes
|
||
|
|
||
|
The [consensus `ExecutionPayload`'s `receipts_root`](https://github.com/ethereum/consensus-specs/blob/67c2f9ee9eb562f7cc02b2ff90d92c56137944e1/specs/capella/beacon-chain.md#executionpayload) now refers to an SSZ [`Root`](https://github.com/ethereum/consensus-specs/blob/67c2f9ee9eb562f7cc02b2ff90d92c56137944e1/specs/phase0/beacon-chain.md#custom-types) instead of an MPT [`Hash32`](https://github.com/ethereum/consensus-specs/blob/67c2f9ee9eb562f7cc02b2ff90d92c56137944e1/specs/phase0/beacon-chain.md#custom-types).
|
||
|
|
||
|
```python
|
||
|
class ExecutionPayload(Container):
|
||
|
...
|
||
|
receipts_root: Root
|
||
|
...
|
||
|
```
|
||
|
|
||
|
To compute the `receipts_root`, the list of individual `Receipt` containers is represented as an SSZ `List`.
|
||
|
|
||
|
```python
|
||
|
receipts = List[Receipt, MAX_TRANSACTIONS_PER_PAYLOAD](
|
||
|
receipt_0, receipt_1, receipt_2, ...)
|
||
|
|
||
|
payload.receipts_root = receipts.hash_tree_root()
|
||
|
```
|
||
|
|
||
|
### Consensus `ExecutionPayloadHeader` changes
|
||
|
|
||
|
The [consensus `ExecutionPayloadHeader`](https://github.com/ethereum/consensus-specs/blob/67c2f9ee9eb562f7cc02b2ff90d92c56137944e1/specs/capella/beacon-chain.md#executionpayloadheader) is updated for the new `ExecutionPayload.receipts_root` definition.
|
||
|
|
||
|
```python
|
||
|
class ExecutionPayloadHeader(Container):
|
||
|
...
|
||
|
receipts_root: Root
|
||
|
...
|
||
|
```
|
||
|
|
||
|
```python
|
||
|
payload_header.receipts_root = payload.receipts_root
|
||
|
```
|
||
|
|
||
|
### Execution block header changes
|
||
|
|
||
|
The [execution block header's `receipts-root`](https://github.com/ethereum/devp2p/blob/bd17dac4228c69b6379644355f373669f74952cd/caps/eth.md#block-encoding-and-validity) is updated to match the consensus `ExecutionPayloadHeader.receipts_root`.
|
||
|
|
||
|
### Networking
|
||
|
|
||
|
The [`recover_encoded_receipt`](../assets/eip-6466/helpers/recover_receipts.py) helper function recovers a receipt's [original representation](https://github.com/ethereum/devp2p/blob/bd17dac4228c69b6379644355f373669f74952cd/caps/eth.md#receipt-encoding-and-validity) for exchange through the [devp2p `Receipts`](https://github.com/ethereum/devp2p/blob/bd17dac4228c69b6379644355f373669f74952cd/caps/eth.md#receipts-0x10) message.
|
||
|
|
||
|
## Rationale
|
||
|
|
||
|
### Should computed transaction fields be included?
|
||
|
|
||
|
The [EIP-6404](./eip-6404.md) `Transaction` SSZ container defines computed fields that are derived from a transaction's original representation. Namely, the `tx_hash` and `tx_from` fields, and also `tx_to` for `DESTINATION_TYPE_CREATE`. Arguments could be made to move them to the `Receipt` SSZ container.
|
||
|
|
||
|
While moving the fields would simplify consensus `ExecutionPayload` a bit, those fields do not fit the semantics of a receipt describing a transaction's outcome after being applied to a state. The fields can be computed without access to a state. Furthermore, for SSZ transactions, the `tx_hash` and `sig_hash` are implicitly available as part of their original representation. Having those hashes in the transaction representation further suggests that they should not be copied into the receipt.
|
||
|
|
||
|
### What about `ReceiptLog` data?
|
||
|
|
||
|
`ReceiptLog` data is formatted according to the Ethereum contract ABI. Merkleizing log data according to its original structure would be more useful than merkleizing it as a `ByteVector`. However, the data structure is determined by the log event signature, of which only the hash is known. As the hash preimages are erased from emitted EVM logs, it is not reliably possible to recover the original log event signature. Therefore, log data is provided as a `ByteVector` for now, with the option for a future EIP to extend it.
|
||
|
|
||
|
## Backwards Compatibility
|
||
|
|
||
|
Applications that solely rely on the `TypedReceipt` RLP encoding but do not rely on the `receipts_root` commitment in the block header can still be used through a re-encoding proxy.
|
||
|
|
||
|
Applications that rely on the replaced MPT `receipts_root` in the block header can no longer find that information. Analysis is required whether affected applications have a migration path available to use the SSZ `receipts_root` instead.
|
||
|
|
||
|
## Test Cases
|
||
|
|
||
|
TBD
|
||
|
|
||
|
## Reference Implementation
|
||
|
|
||
|
TBD
|
||
|
|
||
|
## Security Considerations
|
||
|
|
||
|
None
|
||
|
|
||
|
## Copyright
|
||
|
|
||
|
Copyright and related rights waived via [CC0](../LICENSE.md).
|