Skip to content

Commit 279a7fa

Browse files
authored
Add EIP: Verifiable logs
Merged by EIP-Bot.
1 parent d96b00e commit 279a7fa

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

EIPS/eip-7792.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
eip: 7792
3+
title: Verifiable logs
4+
description: Scheme to make the eth_getLogs response verifiable
5+
author: Etan Kissling (@etan-status), Gajinder Singh (@g11tech), Vitalik Buterin (@vbuterin)
6+
discussions-to: https://ethereum-magicians.org/t/eip-7792-verifiable-logs/21424
7+
status: Draft
8+
type: Standards Track
9+
category: Core
10+
created: 2024-10-21
11+
requires: 6466
12+
---
13+
14+
## Abstract
15+
16+
This EIP defines a method to make the `eth_getLogs` JSON-RPC response verifiable.
17+
18+
## Motivation
19+
20+
The `eth_getLogs` endpoint is used by wallets to obtain the transaction history pertaining to an account or a topic. To verify correctness and completeness of the logs, a wallet would also have to obtain all block headers and check against their logs bloom. However, that mechanism is inefficient due to its high false positive rate and also involves an unpractical amount of network round trips. This EIP defines a replacement mechanism to efficiently and incrementally verify correctness and completeness of `eth_getLogs` responses.
21+
22+
## Specification
23+
24+
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.
25+
26+
### Configuration
27+
28+
| Name | Value |
29+
| - | - |
30+
| `LOG_CONTRACT_ADDRESS` | `0xfffffffffffffffffffffffffffffffffffffffe` |
31+
32+
### Log accumulation
33+
34+
After executing all transactions of a block, commitments of all emitted logs are accumulated into the storage of `LOG_CONTRACT_ADDRESS`. The contract has no code, and its storage layout consists of three slots of type `mapping`. However to prevent [EIP-158](./eip-158.md) cleanup, the contract's nonce is set to `1` at the first write.
35+
36+
| Name | Value | Type |
37+
| `LOG_ADDRESS_STORAGE_SLOT` | `0` | `mapping(address => bytes32)` |
38+
| `LOG_TOPICS_STORAGE_SLOT` | `1` | `mapping(bytes32 => bytes32)` |
39+
| `LOG_ADDRESS_TOPICS_STORAGE_SLOT` | `2` | `mapping(bytes32 => bytes32)` |
40+
41+
Additional metadata about each log's origin is mixed in to each `LogEntry`. The definition uses the `Log` SSZ type as defined in [EIP-6466](./eip-6466.md).
42+
43+
```python
44+
class BlockMeta(Container):
45+
timestamp: uint64
46+
root: Root
47+
48+
class LogMeta(Container):
49+
block: BlockMeta
50+
transaction_root: Root
51+
52+
class Log(Container):
53+
address: ExecutionAddress
54+
topics: List[Bytes32, MAX_TOPICS_PER_LOG]
55+
data: ByteList[MAX_LOG_DATA_SIZE]
56+
57+
class LogEntry(Container):
58+
meta: LogMeta
59+
log: Log
60+
```
61+
62+
The `hash_tree_root(LogEntry)` commitments are subsequently tracked as part of `LOG_CONTRACT_ADDRESS`.
63+
64+
```python
65+
def accumulate_log(evm: Evm, entry_root: Bytes32, key: Bytes32):
66+
root = hashlib.sha256()
67+
root.update(entry_root)
68+
root.update(sload(evm.env.state, LOG_CONTRACT_ADDRESS, key))
69+
sstore(evm.env.state, LOG_CONTRACT_ADDRESS, key, root.digest())
70+
71+
def track_log(evm: Evm, entry: LogEntry) -> None:
72+
entry_root = entry.hash_tree_root()
73+
74+
# Allow verification via `address` filter
75+
key = keccak256(abi.encode(entry.log.address, LOG_ADDRESS_STORAGE_SLOT))
76+
accumulate_log(evm, entry_root, key)
77+
78+
for topic in entry.log.topics:
79+
# Allow verification via `topics` filter
80+
key = keccak256(abi.encode(topic, LOG_TOPICS_STORAGE_SLOT))
81+
accumulate_log(evm, entry_root, key)
82+
83+
# Allow verification via combined `address` + `topics` filter
84+
key = keccak256(abi.encode(entry.log.address, topic))
85+
key = keccak256(abi.encode(key, LOG_ADDRESS_TOPICS_STORAGE_SLOT))
86+
accumulate_log(evm, entry_root, key)
87+
```
88+
89+
### JSON-RPC API
90+
91+
The `eth_getLogs` response format is extended to include:
92+
93+
- `blockTimestamp`: `QUANTITY` - The timestamp field of the block referred to by `blockHash`
94+
95+
### Verification
96+
97+
For `eth_getLogs(address, topics, fromBlock, toBlock)`, the response data can be verified for correctness and completion by obtaining:
98+
99+
1. `fromBlock` and `toBlock` block headers (validated against their known hashes)
100+
2. `fromBlock`'s `parentBlock` header (validated against `fromBlock.parentHash`)
101+
3. Historical log accumulator at `parentBlock` based on given filters (validated with `eth_getProof`)
102+
4. Log accumulator at `toBlock` based on given filters (validated with `eth_getProof`)
103+
104+
Starting from the historical log accumulator from (3), each response entry is applied to it in a way compatible with `accumulate_log` above. If the log accumulator ends up matching the value from (4), the response data is correct and `LogEntry` derived from it can be trusted.
105+
106+
## Rationale
107+
108+
Making the `eth_getLogs` response verifiable adds the necessary security attributes to enable wallets to transition away from relying on trusted data providers, ultimately improving the wallet's privacy guarantees as it is no longer subject to the privacy policy of any given provider.
109+
110+
### Gas cost
111+
112+
The gas cost produced by this scheme is significantly higher than what `LOG#` opcodes produce as of Prague, primarily due to the additional `SLOAD` / `SSTORE` requirement and the double cost of `SHA256` opcodes compared to `KECCAK256` opcodes. The gas cost increases outweigh the savings from dropping logs blooms.
113+
114+
If the mechanism turns out to be prohibitively expensive even when optimized, it may be necessary to move the log accumulators to a separate optimized data structure (not in `state_root`), or to an out-of-protocol zk system. Even then, the gas cost for logs should still reflect the actual overall cost to update a typical out-of-protocol accumulator to deter against log spamming.
115+
116+
## Backwards Compatibility
117+
118+
It is still possible to process `eth_getLogs` responses from trusted servers as is, without verifying them. Client applications with strict response validation may need to be updated to allow the additional `blockTimestamp` field.
119+
120+
## Security Considerations
121+
122+
This scheme reuses existing `eth_getProof` and SSZ Merkle proofs; it does not introduce new security risks.
123+
124+
## Copyright
125+
126+
Copyright and related rights waived via [CC0](../LICENSE.md).

0 commit comments

Comments
 (0)