forked from ethereum/EIPs
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add EIP-6466: SSZ receipts root (ethereum#6466)
* Add EIP: SSZ receipts root * rm transactions reference * Formatting * Fix link * Use title case for titles * SSZ abbrev
- Loading branch information
1 parent
a9708bd
commit 9acd954
Showing
3 changed files
with
205 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
--- | ||
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 | ||
--- | ||
|
||
## Abstract | ||
|
||
This EIP defines a migration process of existing Merkle-Patricia Trie (MPT) commitments for receipts to Simple Serialize (SSZ). | ||
|
||
## 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 their fields, taking advantage of the more modern SSZ format. This brings several advantages: | ||
|
||
1. **Reducing complexity:** Merkle-Patricia Tries (MPT) are hard to work with. Replacing them with SSZ leaves only the state trie in the legacy MPT format. | ||
|
||
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. | ||
|
||
3. **Better for light clients:** Light clients with access to the consensus `ExecutionPayload` no longer need to implement Merkle-Patricia Trie or RLP libraries to work with receipts. | ||
|
||
## 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. | ||
|
||
### Consensus `ExecutionPayload` changes | ||
|
||
A new `Receipt` SSZ container is introduced to represent receipts. | ||
|
||
| Name | SSZ equivalent | | ||
| - | - | | ||
| `Topic` | `Bytes32` | | ||
| [`TransactionType`](./eip-6404.md) | `uint8` | | ||
|
||
| Name | Value | Notes | | ||
| - | - | - | | ||
| [`BYTES_PER_LOGS_BLOOM`](https://github.com/ethereum/consensus-specs/blob/67c2f9ee9eb562f7cc02b2ff90d92c56137944e1/specs/bellatrix/beacon-chain.md#execution) | `uint64(2**8)` (= 256) | Fixed constant | | ||
| `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: Address | ||
topics: List[Topic, MAX_TOPICS_PER_LOG] | ||
data: ByteVector[MAX_LOG_DATA_SIZE] | ||
|
||
class Receipt(Container): | ||
status: uint256 # EIP-658 | ||
cumulative_transaction_gas_used: uint64 | ||
logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM] | ||
logs: List[ReceiptLog, MAX_LOGS_PER_RECEIPT] | ||
|
||
class TypedReceipt(Container): | ||
tx_type: TransactionType | ||
payload: Receipt | ||
``` | ||
|
||
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 new `receipts_root`, the list of individual `TypedReceipt` containers is represented as a SSZ `List`. | ||
|
||
```python | ||
payload.receipts_root = hash_tree_root(List[TypedReceipt, MAX_TRANSACTIONS_PER_PAYLOAD]( | ||
receipt_0, | ||
receipt_1, | ||
receipt_2, | ||
... | ||
)) | ||
``` | ||
|
||
### 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`. | ||
|
||
### Helpers | ||
|
||
These helpers use `TransactionType` constants as defined in [EIP-6404](./eip-6404.md). | ||
|
||
```python | ||
def encode_receipt(receipt: TypedReceipt) -> bytes: | ||
schema = ( | ||
(big_endian_int, receipt.status), | ||
(big_endian_int, receipt.cumulative_transaction_gas_used), | ||
(Binary[256, 256], receipt.logs_bloom), | ||
(List([Binary[20, 20], List([Binary[32, 32]]), Binary[0, uint64(2**24)]]), [ | ||
(log.address, log.topics, log.data) for log in receipt.logs | ||
]), | ||
) | ||
sedes = List([schema for schema, _ in schema]) | ||
values = [value for _, value in schema] | ||
encoded = rlp.encode(values, sedes) | ||
|
||
if receipt.tx_type == TRANSACTION_TYPE_EIP4844: | ||
return [0x05] + encoded | ||
if receipt.tx_type == TRANSACTION_TYPE_EIP1559: | ||
return [0x02] + encoded | ||
if receipt.tx_type == TRANSACTION_TYPE_EIP2930: | ||
return [0x01] + encoded | ||
if receipt.tx_type == TRANSACTION_TYPE_LEGACY: | ||
return encoded | ||
assert False | ||
``` | ||
|
||
```python | ||
def decode_receipt(encoded_receipt: bytes) -> Receipt: | ||
eip2718_type = encoded_receipt[0] | ||
|
||
class RLPReceipt(rlp.Serializable): | ||
fields = ( | ||
('status', big_endian_int), | ||
('cumulative_transaction_gas_used', big_endian_int), | ||
('logs_bloom', Binary[256, 256]), | ||
('logs', List([Binary[20, 20], List([Binary[32, 32]]), Binary[0, uint64(2**24)]])), | ||
) | ||
if eip2718_type == 0x05: | ||
tx_type = TRANSACTION_TYPE_EIP4844 | ||
pre = RLPReceipt.deserialize(encoded_receipt[1:]) | ||
elif eip2718_type == 0x02: | ||
tx_type = TRANSACTION_TYPE_EIP1559 | ||
pre = RLPReceipt.deserialize(encoded_receipt[1:]) | ||
elif eip2718_type == 0x01: | ||
tx_type = TRANSACTION_TYPE_EIP2930 | ||
pre = RLPReceipt.deserialize(encoded_receipt[1:]) | ||
elif 0xc0 <= eip2718_type <= 0xfe: | ||
tx_type = TRANSACTION_TYPE_LEGACY | ||
pre = RLPReceipt.deserialize(encoded_receipt) | ||
else: | ||
assert False | ||
|
||
return Receipt( | ||
status=pre.status, | ||
cumulative_transaction_gas_used=pre.cumulative_transaction_gas_used, | ||
logs_bloom=pre.logs_bloom, | ||
logs=[ReceiptLog( | ||
address=log[0], | ||
topics=log[1], | ||
data=log[2], | ||
) for log in pre.logs], | ||
) | ||
``` | ||
|
||
## Rationale | ||
|
||
This aligns the receipt representation with the [EIP-6404](./eip-6404.md) transaction representation. | ||
|
||
### 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 `receipts_root` in the block header can no longer find that information. | ||
|
||
Receipts are tied to transactions, so are typically tied to either the transaction hash, or to a block hash + sequential transaction index. At time of writing, there is no JSON-RPC endpoint to obtain a receipts proof. It is not expected that major applications rely on the Merkle-Patricia Trie commitment for receipts. | ||
|
||
## Test Cases | ||
|
||
TBD | ||
|
||
## Reference Implementation | ||
|
||
TBD | ||
|
||
## Security Considerations | ||
|
||
None | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](../LICENSE.md). |