# 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.