OP-Syncer

Rust-Native L2 Block Syncer for OP Stack Chains

What I Built

A Rust-native L2 block syncer for OP Stack chains (Base, Optimism). Watches Ethereum L1 for batches posted by the Base sequencer batcher, detects EIP-4844 blob transactions, fetches blob sidecars from the beacon API, and decodes compressed L2 transaction data.

The syncer bridges both Ethereum layers — execution (Nethermind on port 8545) for block headers and blob versioned hashes, and consensus (Prysm on port 3500) for actual blob sidecar payloads. Built on the alloy-rs stack with tokio async runtime. Currently at Milestone 2 of 4, with blob fetching and OP Stack channel frame decoding in progress.

What I Learned

  • EIP-4844 blob architecture: the split between execution and consensus layers means blob data requires two separate API calls — the execution layer stores KZG commitment hashes but not the actual data, which lives on the beacon chain and is pruned after ~18 days.
  • OP Stack derivation pipeline: understanding how L2 batches are compressed (zlib/zstd), framed into channels, and posted to L1 required reading the op-node Go source directly — the spec documentation alone was insufficient for edge cases.
  • alloy-rs ecosystem: Rust-native Ethereum primitives that replace ethers-rs. Strong type safety for transaction parsing, but the ecosystem is still maturing — some blob-specific types needed manual construction.
  • Running your own infrastructure matters: having a self-hosted Ethereum node (Nethermind + Prysm) on Tailscale meant zero rate limits and full control over beacon API access — essential for blob-heavy workloads that would exhaust hosted provider quotas.

Strategic Value

Deep protocol-level understanding of how rollups actually work under the hood — not just using L2s, but reconstructing their state from L1 data. Directly relevant to infrastructure roles at L2 teams, rollup-as-a-service companies, or any organization building on OP Stack.