主页EIPs
EIPsEIP-6466
EIP-6466

SSZ Receipts

Migration of RLP receipts to SSZ
DraftStandards Track: Core
创建时间: 2023-02-08
关联 EIP: EIP-658, EIP-6404
Etan Kissling (@etan-status), Vitalik Buterin (@vbuterin)
社区讨论原文链接编辑
1 分钟了解
欢迎补充好内容
去提交
相关视频
欢迎补充好内容
去提交
正文

Abstract

This EIP defines a migration process of EIP-2718 Recursive-Length Prefix (RLP) receipts to Simple Serialize (SSZ)

Motivation

RLP receipts have a number of shortcomings:

  1. Limited proving support: Due to receipt data being linearly hashed as part of the receipts_root Merkle-Patricia Trie (MPT), it is not possible to efficiently proof individual parts of receipts, such as logs. Requiring the full receipt data to be present can be prohibitive for smart contract based applications such as L2 fraud proofs or client applications verifying log data.

  2. Unnecessary statefulness: EIP-658 replaced the intermediate post-state root from receipts with a boolean status code. However, cumulativeGasUsed is similarly stateful, unnecessarily complicating efforts to execute transactions in parallel. Furthermore, multiple receipts are required to verify the effective gas used by an individual transaction.

  3. Incomplete data: JSON-RPC provides contractAddress in the receipt for a transaction creating a new contract, but the receipt does not contain the required information to verify it. Workarounds that rely on also fetching the transaction data may not be future-proof.

This EIP defines a universal receipt format based on SSZ to address these concerns.

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.

NameValue
MAX_TRANSACTIONS_PER_PAYLOADuint64(2**20) (= 1,048,576)
BYTES_PER_LOGS_BLOOMuint64(2**8) (= 256)
SSZ_TX_TYPE0x1f
NameSSZ equivalent
RootBytes32

Receipt container

All receipts are represented as a single, normalized SSZ container. The definition uses the StableContainer[N] SSZ type and Optional[T] as defined in EIP-7495.

NameValueDescription
MAX_TOPICS_PER_LOG4LOG0 through LOG4 opcodes allow 0-4 topics per log
MAX_LOG_DATA_SIZEuint64(2**24) (= 16,777,216)Maximum data byte length for a log
MAX_LOGS_PER_RECEIPTuint64(2**21) (= 2,097,152)Maximum number of entries within logs
MAX_RECEIPT_FIELDSuint64(2**5) (= 32)Maximum number of fields to which Receipt can ever grow in the future
class Log(Container): address: ExecutionAddress topics: List[Bytes32, MAX_TOPICS_PER_LOG] data: ByteList[MAX_LOG_DATA_SIZE] class Receipt(StableContainer[MAX_RECEIPT_FIELDS]): root: Optional[Hash32] gas_used: Optional[uint64] contract_address: Optional[ExecutionAddress] logs_bloom: Optional[ByteVector[BYTES_PER_LOGS_BLOOM]] logs: Optional[List[Log, MAX_LOGS_PER_RECEIPT]] # EIP-658 status: Optional[boolean] class HomesteadReceipt(Profile[Receipt]): root: Hash32 gas_used: uint64 contract_address: Optional[ExecutionAddress] logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM] logs: List[Log, MAX_LOGS_PER_RECEIPT] class BasicReceipt(Profile[Receipt]): gas_used: uint64 contract_address: Optional[ExecutionAddress] logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM] logs: List[Log, MAX_LOGS_PER_RECEIPT] status: boolean def select_receipt_profile(value: Receipt) -> Type[Profile]: if value.status is not None: return BasicReceipt return HomesteadReceipt

Receipt merkleization

Execution block header changes

The execution block header's receipts-root is transitioned from MPT to SSZ.

receipts = List[Receipt, MAX_TRANSACTIONS_PER_PAYLOAD]( receipt_0, receipt_1, receipt_2, ...) block_header.receipts_root = receipts.hash_tree_root()

Consensus ExecutionPayload changes

When building a consensus ExecutionPayload, the receipts_root is now based on the Receipt type, changing the type of receipts_root from an MPT Hash32 to an SSZ Root.

class ExecutionPayload(Container): ... receipts_root: Root ... class ExecutionPayloadHeader(Container): ... receipts_root: Root ...
payload_header.receipts_root = payload.receipts_root

Networking

When exchanging SSZ receipts via the Ethereum Wire Protocol, the following EIP-2718 compatible envelope is used:

  • Receipt: SSZ_TX_TYPE || snappyFramed(ssz(Receipt))

Objects are encoded using SSZ and compressed using the Snappy framing format, matching the encoding of consensus objects as defined in the consensus networking specification. As part of the encoding, the uncompressed object length is emitted; the RECOMMENDED limit to enforce per object is MAX_CHUNK_SIZE bytes.

Rationale

SSZ merkleization allows verification of individual chunks of receipt data, reducing complexity for client applications and smart contracts. Additionally, SSZ StableContainer enables unification of the receipt format across all EIP-2718 transaction types and provides forward compatibility.

Backwards Compatibility

Applications that rely on the replaced MPT receipts_root in the block header require migration to the SSZ receipts_root.

Applications using verified cumulativeGasUsed values have to compute the value from prior receipts.

Security Considerations

None

Copyright and related rights waived via CC0.

扩展阅读
欢迎补充好内容
去提交
相关项目
欢迎补充好内容
去提交

不想错过最新的 EIP 动态?

订阅 EIPs Fun 周刊以跟进相关更新,建⽴你与 EIP 之间的连接 ,更好地建设以太坊。

详情
支持以太坊贡献者,推动生态建设
资源
GitHub
支持社区