A real-time blockchain block listener with timing anomaly monitoring.
This application connects to a blockchain node via WebSocket and:
- 🎯 Listens to new blocks in real-time
⚠️ Detects timing anomalies (gaps and bursts)- 📊 Displays block information with formatted timestamps
- 🔄 Handles automatic reconnection on disconnection
| Variable | Description | Default |
|---|---|---|
WS_ENDPOINT |
WebSocket endpoint | wss://arbitrum-sepolia-rpc.publicnode.com |
BLOCK_INTERVAL_MS |
Normal interval between blocks (ms) | 250 |
GAP_THRESHOLD_MS |
Gap detection threshold (ms) | 5000 |
RUST_LOG |
Logging level | info |
📦 206943138 | 🕐 2024-01-15 14:30:45.000 UTC | ⏰ 2024-01-15 14:30:45.127 UTC | ⛽ 95893
⚠️ 📦 206943139 - 🕐 7500ms since last block (expected ~250ms) - Gap #1, Total delay: 7250ms
⚡ 📦 206943140 - 🕐 41ms since last block (expected ~250ms) - Burst #1, Speedup: 208ms
- 📦 : Block number
- 🕐 : Block timestamp
- ⏰ : Local timestamp
- ⛽ : Gas used
⚠️ : Gap detected (too long delay)- ⚡ : Burst detected (too short delay)
config.rs: Configuration via environment variablesblock_monitor.rs: Timing anomaly detectionblock_subscriber.rs: WebSocket connection and block managementmain.rs: Entry point and orchestration
[2025-10-21T14:09:29Z INFO block_listener] 🚀 Starting block listener on wss://arbitrum-sepolia-rpc.publicnode.com
[2025-10-21T14:09:29Z INFO block_listener] 📊 Monitoring: 250ms intervals, 5000ms gap threshold
[2025-10-21T14:09:29Z INFO block_listener] Press Ctrl+C to stop
[2025-10-21T14:09:29Z INFO block_listener] Set RUST_LOG=debug to see block details
[2025-10-21T14:09:29Z INFO block_listener::block_subscriber] 🔄 Connecting to wss://arbitrum-sepolia-rpc.publicnode.com
[2025-10-21T14:09:29Z DEBUG tungstenite::handshake::client] Client handshake done.
[2025-10-21T14:09:29Z INFO block_listener::block_subscriber] ✅ Connected to wss://arbitrum-sepolia-rpc.publicnode.com
[2025-10-21T14:09:29Z INFO block_listener::block_subscriber] 📡 Subscribed to new blocks, waiting for data...
[2025-10-21T14:09:29Z DEBUG block_listener::block_subscriber] 🧱 206969997 | 🕐 2025-10-21 14:09:30.000 UTC | ⏰ 2025-10-21 14:09:29.493 UTC | ⛽ 106944
[2025-10-21T14:09:29Z DEBUG block_listener::block_subscriber] 🧱 206969998 | 🕐 2025-10-21 14:09:30.000 UTC | ⏰ 2025-10-21 14:09:29.741 UTC | ⛽ 120269
[2025-10-21T14:09:29Z DEBUG block_listener::block_subscriber] 🧱 206969999 | 🕐 2025-10-21 14:09:30.000 UTC | ⏰ 2025-10-21 14:09:29.979 UTC | ⛽ 722007
[2025-10-21T14:09:30Z DEBUG block_listener::block_subscriber] 🧱 206970000 | 🕐 2025-10-21 14:09:31.000 UTC | ⏰ 2025-10-21 14:09:30.218 UTC | ⛽ 1018864
[2025-10-21T14:09:30Z DEBUG block_listener::block_subscriber] 🧱 206970001 | 🕐 2025-10-21 14:09:31.000 UTC | ⏰ 2025-10-21 14:09:30.452 UTC | ⛽ 217421
[2025-10-21T14:09:30Z DEBUG block_listener::block_subscriber] 🧱 206970002 | 🕐 2025-10-21 14:09:31.000 UTC | ⏰ 2025-10-21 14:09:30.692 UTC | ⛽ 563505
[2025-10-21T14:09:30Z DEBUG block_listener::block_subscriber] 🧱 206970003 | 🕐 2025-10-21 14:09:31.000 UTC | ⏰ 2025-10-21 14:09:30.911 UTC | ⛽ 139503
[2025-10-21T14:09:31Z DEBUG block_listener::block_subscriber] 🧱 206970004 | 🕐 2025-10-21 14:09:32.000 UTC | ⏰ 2025-10-21 14:09:31.175 UTC | ⛽ 986197
[2025-10-21T14:09:31Z DEBUG block_listener::block_subscriber] 🧱 206970005 | 🕐 2025-10-21 14:09:32.000 UTC | ⏰ 2025-10-21 14:09:31.399 UTC | ⛽ 495789
[2025-10-21T14:09:31Z DEBUG block_listener::block_subscriber] 🧱 206970006 | 🕐 2025-10-21 14:09:32.000 UTC | ⏰ 2025-10-21 14:09:31.626 UTC | ⛽ 106944
[2025-10-21T14:09:31Z DEBUG block_listener::block_subscriber] 🧱 206970007 | 🕐 2025-10-21 14:09:32.000 UTC | ⏰ 2025-10-21 14:09:31.867 UTC | ⛽ 599043
[2025-10-21T14:09:32Z DEBUG block_listener::block_subscriber] 🧱 206970008 | 🕐 2025-10-21 14:09:33.000 UTC | ⏰ 2025-10-21 14:09:32.108 UTC | ⛽ 181558
[2025-10-21T14:09:32Z DEBUG block_listener::block_subscriber] 🧱 206970009 | 🕐 2025-10-21 14:09:33.000 UTC | ⏰ 2025-10-21 14:09:32.358 UTC | ⛽ 1086199
[2025-10-21T14:10:26Z WARN block_listener::block_monitor] ⚡ 🧱 206970223 - 🕐 109ms since last block (expected ~250ms) - Burst #1, Speedup: 140ms