Парсинг блокчейну: де ламається збір даних з мережі
Збір даних з мережі виглядає як навчальна задача: підключитися до вузла, забирати блоки, розбирати транзакції. На практиці пропуск блоків і розбіжність балансів спливають через тижні після запуску, коли цифри у звітах уже розійшлися зі станом ланцюга. Розбираємо, у яких місцях ламається парсинг блокчейну і чому це не лікується повторенням запиту.
Пропуск блоків рідко пов'язаний із самою мережею. Вузол обмежує діапазон видачі за один запит, з'єднання рветься на середині, а перезапуск починається не зі збереженого курсора, а з останнього блоку в пам'яті.
Якщо чекпойнт пишеться асинхронно, після падіння процеси розходяться, і діра в історії виявляється лише звіркою підсумків.
Розбіжність балансів дає не переказ, а те, що в транзакції не видно. Внутрішні перекази, виклики контрактів і події з логів потрібно розбирати окремо — інакше баланс сходиться за основною монетою і розходиться за токенами.
Окремий біль: нестандартні реалізації токенів і різна кількість десяткових розрядів, коли сума є, а інтерпретувати її нічим.
Третє місце — перескладання ланцюга. Блоки, уже записані в базу, випадають з канонічної гілки, а перерахунки поверх них зависають і тягнуть за собою всю агрегацію.
Закривається це очікуванням фінальності, ідемпотентним записом і дедуплікацією за ключем, який включає індекс події, а не лише хеш транзакції. Нижче — як ми будуємо конвеєр, де ці збої видно раніше, ніж розійдуться цифри.
Що дає вивірений збір і розбір даних мережі
Перевіряємо результат за чотирма вимірюваними ознаками — їх видно в моніторингу, без ручного розбору логів. Якщо просідає хоча б одна, розбір формально працює, але дані для звітності та звірок уже недостовірні.
- Свіжість даних. Відставання від голови ланцюга вимірюється одиницями блоків, а не десятками, і не зростає під піковим навантаженням: інтервал між появою блоку та записом у сховище тримається стабільним.
- Повнота історії. В обробленому діапазоні немає пропущених висот: кожна транзакція, зміна балансу та виклик контракту прив'язані до свого блоку, розбіжність із джерелом за кількістю записів дорівнює нулю.
- Стійкість до перескладання. Під час відкату ланцюга на кілька блоків записи зі скасованої гілки позначаються недійсними та перераховуються — звітність не «пливе» після перескладання.
- Навантаження на вузол. Читання йде пакетами за діапазонами, зі збереженням курсора та повтореннями при обриві: вузол не захлинається запитами, а довантаження продовжується з останньої обробленої висоти.
- Перевірюваність. Відставання, кількість пропусків і частка повторних спроб виведені в метрики, тому якість даних підтверджується цифрами, а не обіцянками.
Схему розбору перевіряємо на реальних мережах — від Ethereum і сумісних із нею до мереж з іншою моделлю підтверджень.
Набір контрольних звірок добираємо під кожен випадок: десь достатньо звірення з публічним оглядачем блоків, десь потрібен періодичний перерахунок вибраної ділянки історії цілком.
Режими парсингу блокчейну: потік, пакет, за запитом
Режим збору даних визначає задача, а не навпаки. Потокова обробка блоків потрібна там, де важлива свіжість: подія з'являється одразу після підтвердження і йде в обробку без очікування.
Пакетне завантаження історії — коли потрібно відновити стан за довгий відрізок або переіндексувати дані після зміни логіки розбору. Запит за вимогою закриває точкові перевірки, де повний прохід не окупається.
| Режим | Коли підходить | Обмеження |
|---|---|---|
| Потокова обробка блоків | живі панелі, оповіщення, моніторинг адрес | потрібна стійкість до перебудови ланцюга та пропусків, стан зберігається окремо |
| Пакетне завантаження історії | первинне наповнення, переіндексація після зміни логіки | довгий прогін, обмеження вузла на глибину вибірки, обов'язкова ідемпотентність повторів |
| Запит за вимогою | рідкісні точкові перевірки, баланс або виклик контракту на момент часу | не масштабується за обсягом, затримка залежить від доступності вузла |
| Індексація контрактів | регулярні вибірки за подіями та адресами, аналітика | потрібна схема зберігання та правило міграцій, обсяг бази зростає разом з історією |
Як режими поєднуються
На практиці їх комбінують: пакетний прохід наповнює індекс за контрактами та адресами, потік доганяє його новими блоками, а точкові запити читають уже зібрану вітрину.
Загальні вимоги до будь-якої схеми — ідемпотентність повторів, контрольна точка останнього обробленого блоку та окрема обробка перебудов ланцюга. Без цього розбіжності в балансах і пропущені події спливають уже на стороні звітності.
Як ми впроваджуємо парсер: етапи інженерної роботи
Робота йде ітераціями по два-три тижні: кожна закриває одне джерело даних і закінчується перевірюваним артефактом — не звітом, а працюючим індексом, до якого вже можна будувати запити. Порядок етапів однаковий і для однієї мережі, і для набору з кількох.
- Аудит джерел. Інвентаризуємо, звідки беремо дані: повний вузол чи архівний, чи віддає він історичні стани, чи доступні журнали подій контрактів, чи вистачає пропускної здатності на потрібну глибину історії. Тут же фіксуємо список цільових сутностей — транзакції, баланси, виклики контрактів — і те, що в них вважається обов'язковим, а що опціональним.
- Проєктування схеми індексації. Схему будуємо від запитів, а не від структури блоків: розбиваємо таблиці за діапазонами висот, виносимо окремі індекси під адресу, токен і внутрішні перекази. Заздалегідь вирішуємо, що зберігаємо в гарячому вигляді, а що агрегуємо.
- Збір і нормалізація. Налаштовуємо обробку перебудов ланцюга та повторну обробку зачеплених діапазонів, робимо запис ідемпотентним за ключем блоку та операції. Окремо ведемо курсор відставання від голови ланцюга.
- Перевірка повноти. Звіряємо результат із незалежним джерелом: контрольні суми за блоками, кількість подій, підсумкові баланси адрес. Кожна розбіжність іде в чергу розбору зі збереженою сирою відповіддю, щоб причину можна було відтворити.
- Навантажувальні прогони. Проганяємо переіндексацію великого історичного відрізка та паралельні запити, дивимося, де рветься, і налаштовуємо повтори та обмеження темпу звернень до вузла.
- Передача регламентів. Віддаємо інструкції супроводу: як додати новий контракт, що робити при відставанні курсора, як переграти діапазон після збою і як відкотити схему.
Ключ до передбачуваності — на кожному етапі є вимірюваний критерій приймання: глибина проіндексованої історії, частка звірених блоків, допустиме відставання. За ними ж потім видно, що після змін у мережі парсер продовжує сходитися.
Що передаємо на руки: конфігурації, схеми, регламенти
Передаємо не «чорний ящик», а робочий контур, який ваш інженер зможе запустити, прочитати і змінити без нас. Для цього в постачання входить фіксований набір артефактів — від конфігурацій до регламентів, що описують не лише нормальну роботу, а й відновлення після збою.
- Робочі конфігурації сервісів: параметри підключення до вузлів, глибина підтверджень блоку, розмір пакета при перерахунку, ліміти паралельних задач.
- Схема обходу блоків: стартова висота, зберігання контрольних точок, поведінка при пропуску діапазону та при відкаті ланцюга.
- Схема потоку даних: шлях від джерела до нормалізованих таблиць, місця дедуплікації, збагачення та віддачі через програмний інтерфейс.
- Модель зберігання: опис таблиць і зв'язків, індекси під вибірки за адресою, контрактом і періодом, політика архівації старих зрізів.
- Політики доступу: ролі та розмежування прав на читання і на перерахунок, порядок ротації ключів, журнал викликів.
- Документація парсера: призначення полів, формат подій, розшифровка внутрішніх статусів, приклади типових запитів.
- Регламент перерахунку: коли запускати повторний прохід, як обмежити навантаження, щоб не зірвати поточну синхронізацію.
- Набір перевірок і метрик: відставання від мережі, частка помилок розбору, розбіжність балансів, плюс інструкція на випадок інциденту.
Приймання йде на практиці: розгортаємо контур на вашій стороні, проганяємо історичний зріз і звіряємо контрольні суми за вибіркою адрес. Якщо розбіжність виходить за допуск — розбираємо причину до передачі, а не після.
Кейс: індексація мережі без пропусків блоків
Що було до
Клієнт — аналітичний сервіс із навантаженої мережі: баланси адрес, історія транзакцій, статистика за контрактами. Парсинг блокчейну був побудований на опитуванні публічних вузлів «на поточну висоту» — записувалося те, що встигли отримати.
При відставанні вузла або реорганізації блоки випадали мовчки: розрив у висотах знаходили за скаргами користувачів, а не за моніторингом. На вибірковій звірці 500 адрес розбіжності з незалежним оглядачем Etherscan зустрічалися в 3-4% випадків, у пікові дні — до 9%.
Що змінили
Конвеєр перебудували: замість опитування «на останню висоту» — підписка на потік блоків плюс фоновий догін за діапазонами висот. Кожен записаний блок зберігає висоту, хеш і хеш батька, тому розрив ланцюга видно одразу і не маскується наступним блоком.
Реорганізації обробляються відкатом на глибину, задану політикою для мережі, з переіндексацією зачепленого діапазону. Остання підтверджена висота фіксується у сховищі — перезапуск сервісу не дає ні пропусків, ні дублів.
Що стало
Розбіжності на тій самій вибірці — нуль. Повноту підтвердили суцільним проходом за всіма висотами та посторінковою звіркою контрольних сум: кількість проіндексованих блоків збіглася з незалежним джерелом, «дір» в історії немає.
Затримка появи транзакції у зовнішньому інтерфейсі скоротилася з хвилин до секунд, а розсинхрон балансів пішов із класу звернень до підтримки.
Чим архівний вузол відрізняється від полегшеного клієнта
Різниця в тому, що полегшений клієнт зберігає лише заголовки блоків і невеликий набір підтверджених станів, а тіла транзакцій та історичні стани він запитує в інших вузлів у міру потреби.
Архівний вузол тримає весь ланцюг із першого блоку і вміє віддати стан на будь-якій висоті — саме це і називається глибиною історії.
Для парсингу блокчейну це критично. Полегшений клієнт не відтворить стан контракту на торішній висоті: проміжні стани в ньому не зберігаються, а логи подій доступні лише за той інтервал, який вузол встиг обробити.
Повний перерахунок балансів, відновлення власників токенів на довільно вибраний блок або трасування внутрішніх викликів на полегшеному клієнті просто не виконуються.
Ціна архіву — диск і час. Обсяг історії зростає лінійно і ніколи не зменшується, а початкова синхронізація з нуля займає дні, а не години.
Полегшений клієнт стартує швидко і майже не займає місця, але платить за це залежністю від постачальників даних і урізаною глибиною — він годиться для спостереження за поточними подіями, а не для історичних вибірок.
Тому вибір джерела даних у нас завжди йде від задачі, а не від зручності запуску. Якщо потрібен аудит потоків коштів, звірка снепшотів на конкретну висоту або розбір інциденту заднім числом — піднімаємо архівний вузол, а поверх нього власний індексатор із реплікою.
Коли достатньо стежити за новими блоками і віддавати дані в реальному часі, вистачає полегшеного клієнта із зовнішнім постачальником як резервним каналом.
Гібридна схема коштує дорожче в супроводі, але знімає головний ризик — мовчазну втрату історії, через яку перерахунок доводиться починати заново.
Часті технічні сумніви замовників
Сумніви у замовників зазвичай одні й ті самі: що станеться при обриві зв'язку з вузлом, чи не впремось ми в ліміти джерел і чи не витечуть адреси та суми з розібраних транзакцій. Нижче — як ці місця влаштовані в нашій схемі розбору.
Що буде, якщо вузол відвалиться або мережа відкотить блоки?
Парсер зберігає чекпойнт за номером і хешем останнього обробленого блоку, а кожен запис ідемпотентний за ключем «мережа + хеш транзакції + індекс події» — повторний розбір діапазону не створює дублів.
При відкаті глибше глибини підтверджень діапазон перечитується заново, а черга повторів добирає пропущене без ручного втручання.
Чи не створимо ми навантаження на джерела даних?
Працюємо через пул вузлів із ротацією та обмеженням частоти запитів, вибірку логів беремо діапазонами блоків, а не за однією транзакцією. При зростанні потоку додаємо власні вузли — публічні залишаються резервом на випадок деградації.
Як забезпечується приватність даних?
Розбір іде на нашій або вашій інфраструктурі, ключі доступу лежать у секрет-сховищі і не потрапляють у конфігурації. Адреси, суми та зв'язки між гаманцями не передаються третім особам, вивантаження залишаються у вашому контурі, а журнали пишуться без персональних даних.
Наскільки складно додати нову мережу?
Ядро відокремлено від адаптерів мережі: сховище, нормалізація та видача даних перевикористовуються, додається лише шар отримання блоків і розбору логів. Для мереж зі схожою моделлю подій це правка одного адаптера, для нестандартних — окремий розбірник.
Обговоримо вашу задачу зі збору даних з мережі
Щоб повернутися з оцінкою строків і планом робіт, потрібно точно зрозуміти склад даних і межі задачі. Частину вступних закриємо на розмові самі, але чим конкретніший вхід, тим менше правок на етапі приймання.
- Мета розбору. Що має вийти на виході: вітрина звітності, моніторинг адрес, аналітика за контрактами або вивантаження у вашу систему. Від цього залежить глибина парсингу блокчейну і схема зберігання.
- Склад даних. Які мережі та сутності потрібні — транзакції, перекази токенів, баланси, події контрактів; за який період і як часто оновлювати.
- Джерела доступу. Свої повні вузли чи зовнішні, обмеження на частоту запитів, чи є ключі до оглядачів мережі.
- Поточний контур. Куди складати результат: наявна база, сховище, обмін файлами; які ліміти за навантаженням і правами доступу.
- Складність контрактів. Чи достатньо стандартних подій або потрібен розбір внутрішніх викликів, нестандартних токенів і відновлення сум за логами.
- Вимоги до звірки. Наскільки критична повнота: чи допустиме відставання від мережі, чи потрібні перерахунки при реорганізаціях ланцюга.
- Обмеження. Галузеві вимоги, розмежування доступу до адрес, правила зберігання прив'язок.
Опишіть задачу у вільній формі — обговоримо деталі та повернемося з оцінкою строків, складом даних і планом робіт за етапами. Якщо частина відповідей поки не готова, розберемо їх на першій розмові та зафіксуємо письмово.







