Злиття даних з різних ланцюгів
(Розділ: Екосистема та Мережа)
1) Навіщо потрібно злиття
Злиття (cross-chain merge) об'єднує події/стани з різних ланцюгів, мостів і сервісів в єдину консистентну модель даних для фінансової звітності, аналітики, анти-фрода, спостережуваності і продуктових сценаріїв. Цілі:- Єдине джерело правди (canonical facts) при наявності різношерстих логів.
- Стійкість до реоргів і затримок: коректна фіналізація та переобрахування.
- Порівнянність метрик між мережами та активами.
- Прозорий lineage і контроль якості для аудиту і регуляторів.
2) Джерела та класи даних
1. Ончейн: блоки, транзакції, логи контрактів, заголовки, стани.
2. Мости/релеєри: заявки, квитанції, докази, статуси фіналізації.
3. L2/DA шари: батчі, публікації, пруфи, вікна оспорювання.
4. PSP/KYC/KYB/AML: платіжні статуси, перевірки, санкційні хіти.
5. Продуктові події: онбординг, депозити/виплати, ігрові та поведінкові події.
6. Довідники: мережі, активи, decimals, chainId, адреси, версії SDK.
Для кожного джерела фіксуються: власник, схема, лаг оновлення, вікно фіналізації, формат доказів і SLO.
3) Архітектура пайплайна злиття
Ingest (агенти/індексери/webhook) → Raw/Bronze (незмінна сировина) → Clean/Silver (нормалізація і дедуп) → Merge/Core/Gold (канонічні факти і зв'язки) → Marts (фінанси/продукт/ризик/операційка) → Serve (OLAP/API/пошук).
Ключові властивості: ідемпотентність, версіонування схем, replay/backfill, late data handling.
4) Канонічні схеми (спрощено)
4. 1 Події (YAML)
yaml event:
id: uuid observed_at: timestamp # when saw event_at: timestamp # when happened (by source)
chain_id: string # 'eth-mainnet' 'polygon'...
block_height: long tx_hash: string log_index: int type: string # transfer bridge. lock bridge. mint...
status: string # observed confirmed finalized invalid src: string # address/peer-id/org _ id dst: string asset: string # canonical character (USDC)
amount: decimal usd_value: decimal # normalization at the rate on the meta observed_at: object # gas, fee, contract, sdk_version...
idempotency_key: string # chainId block tx logIndex type proof_ref: string # proof/anchor reference
4. 2 Переклади та мости (SQL)
sql
CREATE TABLE bridge_transfers (
id TEXT PRIMARY KEY,
src_chain TEXT, dst_chain TEXT,
asset TEXT, amount NUMERIC,
created_at TIMESTAMPTZ,
finalized_at TIMESTAMPTZ,
status TEXT, -- requested inflight finalized failed reversed src_tx TEXT, dst_tx TEXT,
proof_ref TEXT, meta JSONB
);
4. 3 Довідник активів/мереж (YAML)
yaml catalog:
assets:
- symbol: USDC decimals: { eth-mainnet: 6, polygon: 6 }
contracts: { eth-mainnet: "0xA0b8...", polygon: "0x2791..." }
networks:
- id: eth-mainnet k_confirmations: 12
- id: polygon k_confirmations: 256
5) Фіналізація, реорги і статуси
Стани: `observed → confirmed(K) → finalized → invalidated(reorg)` (+ `challenged` для optimistic).
Політики:- K-підтверджень по мережі/активу/ризику.
- Delayed Finalization для великих сум.
- Reorg handling: автоматична інвалідація та replay.
- Proof coverage: частка записів з пруфами/анкерами ≥ цільового SLO.
6) Нормалізація часу і валют
Час: всі timestampts в UTC, зберігати'observed _ at'і'event _ at'.
FX/ціни активів: перерахунок'usd _ value'за курсом на'observed _ at'( або'event _ at'- для звітності, визначено політикою).
Decimals/scale: сувора канонізація кількостей для порівнянності.
Часові пояси у звітах: резолвятся при відборі (вітрина), не в core.
7) Ідемпотентність і дедуплікація
Базовий ключ дедупа:- `idempotency_key = chainId|block_height|tx_hash|log_index|type`
- Повтори з декількох індексерів - upsert за idempotency_key.
- При конфлікті payload - спрацьовує policy of truth (пріоритет джерела/версія/час).
- Вікно дедупа зберігається ≥ 48-72 год для «блукаючих» повторів.
8) Entity Resolution (зіставлення сутностей)
Адреси → актори: гаманець/контракт → користувач/організація/роль.
Зв'язки крос-ланцюга: hard-link (підпис/kyc), soft-link (поведінка/граф).
Псевдонімізація: стабільний PID/ORG_ID; PII зберігається у контролера даних.
9) Правила злиття та пріоритети (Policy)
1. Джерело істини за фактом перекладу - ончейн подія'finalized'+ пруф.
2. Джерело істини по агрегатах - core таблиці'transfers'bridge _ transfers', а не «сировина».
3. Конфлікт часу (event_at vs observed_at) - по політиці звіту (фінанси - event_at; операційка - observed_at).
4. Конфлікт сум/активів - зупинка мерджу і карантин до звірки каталогу активів.
5. Мостові зв'язки - потрібні квитанції обох сторін (src/dst) + receipt pairing.
10) Псевдо-запити та алгоритми
10. 1 Зведення подій в канонічну «операцію»
sql
WITH base AS (
SELECT e.,
CONCAT(e. chain_id,' ',e. block_height,' ',e. tx_hash,' ',e. log_index,' ',e. type) AS idem
FROM raw_events e
)
INSERT INTO core_events AS c (id, observed_at, event_at, chain_id, block_height,
tx_hash, log_index, type, status, src, dst, asset, amount, usd_value, meta, idempotency_key, proof_ref)
SELECT gen_random_uuid(), observed_at, event_at, chain_id, block_height,
tx_hash, log_index, type, status, src, dst, asset, amount, usd_value, meta, idem, proof_ref
FROM base
ON CONFLICT (idempotency_key) DO UPDATE
SET status = EXCLUDED. status,
usd_value = COALESCE(EXCLUDED. usd_value, core_events. usd_value),
proof_ref = COALESCE(EXCLUDED. proof_ref, core_events. proof_ref),
meta = core_events. meta EXCLUDED. meta;
10. 2 Матчинг мостових пар (istochnik↔tsel)
sql
INSERT INTO bridge_transfers (id, src_chain, dst_chain, asset, amount, created_at, status, src_tx, proof_ref)
SELECT
CONCAT('br:', e. tx_hash) AS id,
e. chain_id, b. dst_chain, e. asset, e. amount, e. event_at, 'inflight', e. tx_hash, e. proof_ref
FROM core_events e
JOIN bridge_book b ON e. type='bridge. lock' AND e. asset=b. asset AND e. chain_id=b. src_chain
ON CONFLICT (id) DO NOTHING;
UPDATE bridge_transfers bt
SET finalized_at = e. event_at,
dst_tx = e. tx_hash,
status = 'finalized'
FROM core_events e
WHERE e. type='bridge. mint'
AND bt. status='inflight'
AND bt. asset=e. asset
AND bt. src_chain=bridge_book. src_chain
AND bt. dst_chain=bridge_book. dst_chain
AND abs(e. amount - bt. amount) < 1e-9;
10. 3 Обробка реоргів
sql
UPDATE core_events
SET status='invalidated'
WHERE chain_id=$1 AND block_height BETWEEN $2 AND $3
AND status IN ('observed','confirmed','finalized');
-- Reassembly of aggregates (example)
CALL recompute_materialized_views($1, $2, $3);
11) Управління схемами та еволюцією
Версіонування: 'schema _ version'в шапці набору даних, міграції записуються в журнал.
Політика сумісності: 'BACKWARD'для подій (тільки додавання полів).
Data Contracts з джерелами: тести контрактів в CI, лінтери схем.
12) Якість даних: SLI/SLO
SLI (приклад):- Freshness p95: лаг ingest→Gold (хв).
- Completeness %: частка записів, що досягли «finalized» в межах вікна.
- Correctness %: валідні схеми/підписи/пруфи.
- Proof Coverage %: частка канонічних записів з пруфами/анкерами.
- Dedup Efficiency: частка дублів, поглинених ідемпотентно.
- Reorg Handling Success %: коректно інвалідацій і replays.
SLO (орієнтири): Freshness ≤ 3 хв (стрім )/15 хв (батч); Completeness ≥ 99. 7%; Correctness ≥ 99. 9%; Proof Coverage ≥ 99. 0%; Reorg Success ≥ 99. 9%; Merge MTTR (інцидент) ≤ 30 хв.
13) Дашборди (макети)
Merge Ops (реал-тайм/год): Freshness, Queue lag, Dedup rate, Finalized %, Reorg spikes, Error-budget burn.
Proof & Finality: proof coverage, p95 finality per chain, challenge/reorg события.
Catalog Health: розбіжності меппінгів активів, decimals, версій SDK.
Quality & Drift: completeness/correctness, schema drift, late data.
Finance Lens: GTV, Net Flow, TVL по ланцюгах/мостах (тільки'finalized').
14) Конфігурації (YAML)
Вікна фіналізації
yaml finality:
eth-mainnet: { k: 12, delayed_for_usd_gt: 100000 }
polygon: { k: 256 }
optimistic-L2:
k: 0 challenge_minutes: 20 delayed_for_usd_gt: 50000
Політика мерджа і пріоритетів
yaml merge_policy:
source_priority: [onchain, bridge, psp, product]
conflict:
time: { prefer: "event_at" }
amount: { action: "quarantine" }
proof_required_for: ["bridge_transfers", "payouts"]
quarantine_topics: ["asset_mismatch", "decimals_mismatch", "time_skew_gt_5m"]
Ідемпотентність/дедуп
yaml dedup:
key_template: "${chain_id} ${block_height} ${tx_hash} ${log_index} ${type}"
ttl_hours: 72
15) Приватність і комплаєнс
PII-мінімізація: PID/ORG_ID, заборона PII в метриках/лейблах.
Data residency: сегрегація регіонів (EU/ROW), шифрування «в спокої/в дорозі».
Право на видалення: tombstone/redaction події з доказовим застосуванням.
Аудит: незмінні журнали, анкеринг хешів, перевірка доступу за ролями.
16) Операційні регламенти
Щодня: звірка proof coverage, фіналізація по ланцюгах, реєстр мостів і конфіг-дрейф.
Щотижня: ревізія каталогу активів/decimals, коректність FX-нормалізації.
Щомісяця: тести reorg/replay, перевірка SLO і стрес-тест продуктивності.
Change Management: timelock на зміни merge-політики, журнал рішень.
17) Playbook інцидентів
A. розсинхрон активів/decimals
Стоп на відповідні активи, відкат каталогу, перерахунок вітрин, звіт ≤ 24 год.
B. Падіння Proof Coverage
Перезапуск мерклізації/анкерингу, підвищення рівня логування, ручна вибірка 100 кейсів, звіт.
C. піки Reorg/Challenge
Збільшити'k '/вікно спору, включити delayed finalization для великих сум, повідомити зацікавлених.
D. вибух дублів/повторів
Посилити дедуп TTL/ключ, обмежити «галасливі» джерела, включити карантин-контур.
E. дрейф часу (time skew)
Синхронізація NTP/PTP, перерахунок вікон, тимчасовий зсув політики'prefer: observed_at`.
18) Чек-лист впровадження
1. Зафіксуйте джерела, вікна фіналізації та докази.
2. Впроваджуйте канонічну схему подій і ключ ідемпотентності.
3. Налаштуйте дедуп і merge-політику з quarantine-контуром.
4. Підніміть реєстр активів/мереж і FX-нормалізацію.
5. Реалізуйте replay/backfill і обробку late data.
6. Визначте SLI/SLO і дашборди якості.
7. Запустіть регулярний анкеринг та аудит-журнали.
8. Проведіть пілот з симуляціями реоргів/мостових затримок і зафіксуйте MTTR.
19) Глосарій
Finality - незворотність стану/події.
Reorg - перезбірка ланцюга з ануляцією частини блоків.
Idempotency - стійкість до повторної доставки.
Proof Coverage - частка записів з валідними доказами.
Entity Resolution - зіставлення адрес/акаунтів єдиної сутності.
Delayed Finalization - відкладене прийняття в агрегати для високоризикових сум.
Quarantine - ізольований потік для конфліктних/підозрілих записів.
Підсумок: коректне злиття міжчіпних даних - це керована дисципліна: канонічна схема, фіналізація і пруфи, сувора ідемпотентність, прозора політика злиття і спостережуваність якості. Слідуючи цьому фреймворку, екосистема отримує єдиний, перевіряється і стійкий шар даних - основу для аудиту, аналітики і безпечного масштабування продуктів.