Розробка системи мониторингу контрактів на кількох сетях
Мультисетевий мониторинг — це не просто "запустити кілька Etherscan вкладок". Коли протокол працює одночасно на Ethereum, Arbitrum, Polygon, Base та Optimism, і между ними ходять bridged активи, затримка в обнаруженні аномалії в одній сети може коштувати коштів користувачів в іншій. Проблема не в отриманні даних — дані доступні. Проблема в правильній агрегації, кореляції подій між сетями та швидкості реакції.
Архітектура мониторингової системи
Джерела даних
RPC nodes — прямі вызови до EVM-нод через WebSocket для real-time подій. Для кожної сети потребен надійний RPC з підтримкою eth_subscribe:
// Підписка на години контракту через WebSocket
const provider = new ethers.WebSocketProvider(RPC_WS_URL);
const contract = new ethers.Contract(address, abi, provider);
contract.on('Transfer', (from, to, value, event) => {
emitEvent({
network: 'arbitrum',
block: event.log.blockNumber,
txHash: event.log.transactionHash,
type: 'Transfer',
data: { from, to, value }
});
});
Проблема single RPC: публічні ноди ненадійні, пропускають години при нагрузці. Розв'язок: мінімум 2 незалежні провайдери на сеть (Alchemy + QuickNode, або власна нода). Дедупліканція по (chainId, txHash, logIndex).
The Graph / Subgraph — для історичних даних та складних запитів. Шар медіації поверх raw RPC. Latency 1–3 блоки, ідеально для аналітичних запитів та cross-network сверки балансів.
Дефолтні параметри по сетям:
| Сеть | Block time | Рекомендований RPC | Finality |
|---|---|---|---|
| Ethereum | ~12 sec | Alchemy/Infura | ~64 блоки (~13 хв) |
| Arbitrum One | ~0.25 sec | Arbitrum RPC / Alchemy | L1 finality |
| Polygon PoS | ~2 sec | Polygon RPC / QuickNode | ~256 блоків |
| Base | ~2 sec | Base RPC / Alchemy | L1 finality |
| Optimism | ~2 sec | Optimism RPC / Alchemy | L1 finality |
Event Processing Pipeline
Сирі години не можна одразу аналізувати — потрібна нормалізація та збагачення:
RPC Listener → Message Queue (Kafka/Redis Streams) → Event Processor → Alert Engine → Notification
↓
Time-series DB (InfluxDB/TimescaleDB)
↓
Analytics Dashboard
Message Queue буферизує спайки. При різкому зростанні on-chain активності (наприклад, великий liquidation cascade) години приходять швидше ніж можна обробити. Kafka з retention 24h дозволяє replay.
Event Processor нормалізує години з різних сетей в єдиний формат, декодує ABI, збагачує (ціни токенів, метадані акаунтів), детектує аномалії.
Alert Engine застосовує правила до нормалізованих подій. Stateful правила потребують state store (Redis). Приклади:
class LargeTransferAlert(AlertRule):
def evaluate(self, event: NormalizedEvent) -> Optional[Alert]:
if event.type != 'Transfer':
return None
usd_value = event.data['value'] * get_token_price(event.data['token'])
threshold = self.get_dynamic_threshold(
token=event.data['token'],
window='24h',
multiplier=10.0 # 10x від 24h середнього
)
if usd_value > threshold:
return Alert(
severity='HIGH',
message=f'Large transfer: ${usd_value:,.0f} on {event.network}',
context=event
)
Cross-Chain Correlation
Найцінніша функціональність для мультисетевих протоколів — зв'язування подій між сетями. Типові сценарії:
Bridge monitoring — токен заблокований на Ethereum, повинен з'явитися на Arbitrum. Якщо не з'явився за N хвилин — алерт.
class BridgeCorrelator:
def __init__(self, redis_client):
self.pending = {} # bridge_tx_hash -> pending event
def on_bridge_initiated(self, event):
key = f"bridge:{event.src_chain}:{event.tx_hash}"
self.redis.setex(key, 3600, json.dumps(event.to_dict()))
def on_bridge_completed(self, event):
key = f"bridge:{event.src_chain}:{event.bridge_nonce}"
pending = self.redis.get(key)
if not pending:
alert(f"Bridge completion without initiation: {event}")
return
initiation = json.loads(pending)
latency = event.timestamp - initiation['timestamp']
if latency > EXPECTED_BRIDGE_LATENCY[event.bridge_protocol]:
alert(f"Bridge latency anomaly: {latency}s")
TVL consistency check — суммарний TVL на L2s не повинен перевищувати locked amount на L1. Періодична перевірка через subgraph запити з алертом при розхожденні > X%.
Що мониторити: практичний список
Security-критичні години
-
Ownership transfers —
OwnershipTransferred,RoleGrantedна будь-якому контракті протоколу - Upgrade proposals — години від Timelock (нові proposals, виконання)
- Великі виводи — вивід > N% TVL за короткий період
- Flash loan usage — отримання flash loan + взаємодія з контрактом в одній tx
- Oracle price deviations — ціна в протоколі відхиляється від ринку > X%
- Pause года — хтось паузив контракт
Operational метрики
- Gas usage аномалії (спайк може означати inefficient execution або атаку)
- Failed транзакцій доля (зростання failed tx у routera може означати UI/API баг)
- Block inclusion latency для власних транзакцій (keeper bots, liquidation bots)
Business метрики
- TVL динаміка по сетях
- Volume по сетях
- Unique активних адрес
- Protocol revenue (зібрані fees)
Технічний стек
OpenZeppelin Defender — якщо протокол використовує OZ, Defender Sentinel покриває базовий моніторинг з мінімальною налаштуванням. Обмеження: слабка cross-chain корелянція, нема кастомної аналітики.
Tenderly Alerts — хорошо для development/staging, покриває основні сети. Для production критичних систем — будувати поверх.
Власна система — виправдана коли: потрібна cross-chain корелянція, специфічна business-логіка в алертах, інтеграція з внутрішніми системами, >10 контрактів на >3 сетях.
Стек для кастомної системи:
- Event ingestion: Node.js + ethers.js WebSocket listeners
- Message queue: Redis Streams (малі проекти) або Kafka (висока нагрузка)
- Storage: TimescaleDB для time-series, PostgreSQL для метаданих
- Alert rules: Python з rule engine
- Notifications: PagerDuty/OpsGenie для критичних, Telegram/Discord для операційних
- Dashboard: Grafana над TimescaleDB
Реакція на алерти: не лише сповіщення
Моніторинг без автоматичної реакції — половина системи. OpenZeppelin Defender Autotask або кастомний keeper бот:
- Аномально великий вивід → автоматична пауза контракту (якщо pauser налаштований на keeper)
- Oracle deviation → переключення на fallback oracle
- Bridge stuck > 2 години → сповіщення bridge operator + створення тикета
Автоматична реакція потребує ретельного аудиту самого keeper бота — він стає критичним елементом безпеки.
Дашборди
Grafana дашборди по структурі: Overview (всі ноди, всі сети, статус з першого погляду), Per-network deep dive (детальні метрики по кожній сети), Validator performance (для стейкинговых нод, включаючи APR та slashing ризики), Infrastructure (CPU/RAM/Disk по нодам).
Для публічних RPC-сервісів додатково: метрики запитів (RPS, latency, error rate), статистика rate limiting, топ методів по нагрузці.
Таймлайн розробки
| Компонент | Таймлайн |
|---|---|
| Базові експортери (EVM + 1–2 інші сети) | 1–2 тижні |
| Prometheus + VictoriaMetrics + Grafana | 3–5 днів |
| Alert правила + PagerDuty/Telegram інтеграція | 2–3 дні |
| Auto-failover для RPC | 1 тиждень |
| Дашборди + документація | 1 тиждень |
Моніторинг для 3–5 сетей з базовими дашбордами та алертами — 3–4 тижні. Розширена система з auto-remediation та кастомними експортерами для нестандартних протоколів — 6–8 тижнів.







