# ERC-20 Transfer (Reth ExEx)
## Motivation
Indexing ERC-20 Transfer logs is a foundational primitive for wallets, analytics. ExEx is ideal here because it:
- runs in-process with Reth (no RPC round-trips),
- receives canonical block notifications and reorg signals, and
## Architecture
```mermaid
flowchart LR
subgraph RethNode [Reth Node - same process]
A[Execution Pipeline] --> B[Canon State Notifications]
B -->|ChainCommitted / ChainReorged / ChainReverted| C[ERC20 Transfer ExEx]
C --> D[Segment Buffer]
D --> E[WAL + Sink Writer]
C -->|ExExEvent::FinishedHeight| F[ExEx Manager / Pruner]
end
E -->|SQLite| S1[(db.sqlite)]
E -->|RocksDB| S2[(rocks/)]
E -->|Parquet| S3[(lake/yyyy/mm/dd/hh/*.parquet)]
E -->|Kafka| S4[(topic: erc20.transfer)]
```
# Reth ExEx: Core Responsibilities and Technical Breakdown
The Reth Execution Extension (ExEx) is a powerful, in-process component designed to process blockchain data efficiently. Its primary function is to consume notifications from the Reth node, extract specific on-chain information like ERC-20 token transfers, and persist this data reliably.
---
## 🚀 Core Responsibilities
* **Notification Handling**: The ExEx listens for notifications from Reth, including `ChainCommitted` for new blocks and `ChainReorged` / `ChainReverted` for chain reconfigurations.
* **Data Extraction**: It scans logs within committed blocks, filtering for specific events like `Transfer(address,address,uint256)`, and then normalizes this data into a structured format.
* **Atomic Commits**: Data is buffered in segments and written atomically to a configurable storage backend (the "sink"), ensuring data integrity.
* **Reorg Safety**: In case of a chain reorganization, the ExEx automatically rolls back its data to a common ancestor, deletes or marks orphaned rows, and then reprocesses the new canonical chain segment.
* **Backfill and Live Processing**: The same core pipeline is used for both historical data backfilling and continuous live processing, with periodic updates to Reth to enable **Write-Ahead Log (WAL) pruning**.
* **Finished Height Handshake**: A handshake mechanism signals to Reth the highest block the ExEx has successfully processed, which helps manage and prune the ExEx's WAL.
---
## 🛠️ Component Breakdown
The ExEx is modular, with key components handling specific functions:
* **`runner`**: The main orchestrator that manages the notification loop and event emissions.
* **`pipeline/scan`**: The core logic for filtering and extracting data from logs.
* **`sink/`**: A pluggable interface for various data storage backends, responsible for all data persistence logic.
* **`reorg/`**: Provides the logic to safely handle rollbacks during chain reconfigurations.
* **`metrics/`**: Collects key performance indicators like **tip lag** (the difference between Reth's tip and the ExEx's finished height), throughput, and commit latency.
---
## 💻 Tech Stack
* **Language & Runtime**: Built in **Rust** using `async/await` for asynchronous operations. The ExEx runs as a `Future` polled by the Reth runtime.
* **Reth Integration**: Requires Reth `1.5.x` or later. It communicates with Reth through dedicated notification and event channels.
* **Pluggable Sinks**: Supports various storage solutions, including:
* **SQLite**: Uses WAL mode for concurrency and atomic transactions per segment.
* **RocksDB**: Leverages column families for efficient key-value storage.
* **Parquet**: Writes to partitioned staging files, which are then atomically promoted.
* **Kafka**: Streams data to a Kafka topic, with an optional outbox table for exactly-once delivery.
* **Serialization**: Data is packed into a binary format using crates like `serde`, optimizing storage and retrieval.