SSZ receipts
相关视频
正文
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:
-
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. -
Unnecessary statefulness: EIP-658 replaced the intermediate post-state
root
from receipts with a booleanstatus
code. However,cumulativeGasUsed
andlogIndex
are similarly stateful, unnecessarily complicating efforts to execute transactions in parallel. Further,gasUsed
verification requires computation fromcumulativeGasUsed
across multiple receipts. -
Incomplete data: JSON-RPC provides
from
,gasUsed
, andcontractAddress
fields for receipts, but the on-chain receipt does not contain the required information to verify them. -
Inefficient logs bloom: The logs bloom mechanism is inefficient due to its high false positive rate. It does not find enough practical use to warrant its high storage requirement, and should be removed.
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.
Name | SSZ equivalent |
---|---|
Root | Bytes32 |
ExecutionAddress | Bytes20 |
GasAmount | uint64 |
Logs
Logs are represented as an SSZ Container
.
Name | Value | Description |
---|---|---|
MAX_TOPICS_PER_LOG | 4 | LOG0 through LOG4 opcodes allow 0-4 topics per log |
class Log(Container): address: ExecutionAddress topics: List[Bytes32, MAX_TOPICS_PER_LOG] data: ProgressiveByteList
Receipts
New receipts use a normalized SSZ representation.
class Receipt(CompatibleUnion[ BasicReceipt, CreateReceipt, SetCodeReceipt, ]): pass
Basic receipts
This receipt is emitted for these transactions:
RlpLegacyReplayableBasicTransaction
RlpLegacyBasicTransaction
RlpAccessListBasicTransaction
RlpBasicTransaction
RlpBlobTransaction
class BasicReceipt( ProgressiveContainer[active_fields=[1, 1, 0, 1, 1]] ): from_: ExecutionAddress gas_used: GasAmount logs: ProgressiveList[Log] status: boolean
Create receipts
This receipt is emitted for these transactions:
RlpLegacyReplayableCreateTransaction
RlpLegacyCreateTransaction
RlpAccessListCreateTransaction
RlpCreateTransaction
class CreateReceipt( ProgressiveContainer[active_fields=[1, 1, 1, 1, 1]] ): from_: ExecutionAddress gas_used: GasAmount contract_address: ExecutionAddress logs: ProgressiveList[Log] status: boolean
EIP-7702 set code receipts
This receipt is emitted for these transactions:
class SetCodeReceipt( ProgressiveContainer[active_fields=[1, 1, 0, 1, 1, 1]] ): from_: ExecutionAddress gas_used: GasAmount logs: ProgressiveList[Log] status: boolean authorities: ProgressiveList[ExecutionAddress]
Receipt
construction
Receipts are constructed as follows.
Field | Description |
---|---|
from | The transaction sender's address |
gas_used | How much gas this individual transaction used. Replaces cumulative_gas_used |
contract_address | For transactions deploying a contract, the new contract address |
logs | Logs emitted during transaction execution |
status | EIP-658 transaction status code |
authorities | For transactions with an authorization list, the list of EIP-7702 authority addresses. Non-successful authorizations are represented with an all-zero address |
The logs_bloom
and intermediate state root
(Homestead scheme) are not present in SSZ receipts.
Execution block header changes
The execution block header's receipts-root
is transitioned from MPT to SSZ.
receipts = ProgressiveList[Receipt]( receipt_0, receipt_1, receipt_2, ...) block_header.receipts_root = receipts.hash_tree_root()
JSON-RPC API
Transaction receipt objects in the context of the JSON-RPC API are extended to include:
authorities
:Array of DATA|null
- Array ofDATA
entries each containing 20 Bytes, corresponding to the receipt'sauthorities
field
Within logs
, the logIndex
field is changed to indicate the log index position in the individual receipt, rather than in the entire block.
The logsBloom
field is no longer returned for new receipts. It continues to be returned for historical receipts conforming to earlier schemes.
from
, gasUsed
, and contractAddress
are already provided via JSON-RPC and are left unchanged.
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(...): ... receipts_root: Root ... class ExecutionPayloadHeader(...): ... receipts_root: Root ...
payload_header.receipts_root = payload.receipts_root
Rationale
Forward compatibility
All receipts share the same Merkle tree shape with a stable generalized index (gindex) assigned to each field. Future transaction features can introduce additional receipt fields or drop existing fields without breaking verifiers.
Verifier improvements
Committing to from
, contract_address
and authorities
in the receipt allows efficient verification without the expensive ecrecover
mechanism. This allows future EIPs to change how these addresses are computed without breaking verifiers, e.g., when future signature schemes are introduced.
Execution client improvements
Execution Layer implementations no longer need access to the transaction and additional indices when serving receipts based on SSZ.
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.
Applications relying on the logsBloom
will have to swap to an out-of-protocol mechanism for filtering logs, or fall back to processing the complete set of receipts. As the logsBloom
mechanism was prohibitively inefficient for light clients, its removal is unlikely to have a significant impact.
Applications relying on the per block logIndex
now have to compute this data, as logIndex
now refers to an index per receipt.
RLP and SSZ receipts may clash when encoded. It is essential to use only a single format within one channel. When requesting receipts by hash over the network, the block header corresponding to the containing receipts root can be consulted to identify the underlying fork.
Security Considerations
None
Copyright
Copyright and related rights waived via CC0.