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







