Почему парсинг блокчейн-эксплореров становится узким местом
Когда индекс транзакций строится поверх публичных блокчейн-эксплореров вроде Etherscan, всё упирается в чужие правила игры. Парсинг блокчейн эксплореров держится на лимитах запросов к внешним сервисам: суточные квоты, окна по частоте обращений, обязательная постраничная выборка по курсору. На длинных диапазонах это даёт рваную историю блоков — обход обрывается на середине, а повтор с того же курсора возвращает уже другой срез данных.
Вторая беда — неполные данные транзакций. Внешний сервис может не отдать внутренние переводы, события контрактов или статус финальности, а часть адресов помечается как исполняемый код только по факту его появления в сети. В итоге один и тот же блок у двух источников описывается по-разному: суммы сходятся, а состав операций — нет. Время команды уходит не на аналитику, а на ручные сверки и разбор расхождений.
Дальше включается узкое место индексации: пока данные догружаются, отчёты, уведомления и балансы кошельков показывают вчерашнее состояние. Один пропущенный блок тянется через всю цепочку зависимых расчётов и всплывает уже у клиента — в выгрузке, сверке или решении по риску.
Мы проходили этот путь: начинали со сборки выборок через публичные интерфейсы и упирались ровно в те же потолки. Разбираем, как это закрывается и где заканчивается внешний сервис, а начинается контур, который вы контролируете сами.
Что даёт управляемый конвейер разбора блокчейн-данных
Через публичные обозреватели данные идут неравномерно: темп сбора задаёт не наш конвейер, а внешний лимит запросов. Стоит превысить порог — часть запросов возвращается с отказом, и если обработчик не ведёт журнал диапазонов, эти блоки выпадают из реестра. Ошибка вскрывается не сразу, а на сверке балансов через недели, когда восстановить пропуск дороже, чем собрать данные заново.
Собственная нода снимает этот класс отказов. Мы читаем блоки напрямую из журнала событий и держим указатель на последний обработанный блок, поэтому лимиты внешнего поставщика перестают задавать темп. Сбор идёт непрерывно: очередь наполняется из ноды, а не из ответов чужого сервиса. Etherscan и подобные обозреватели остаются полезны для выборочной перепроверки транзакций.
Целостность реестра держится на идемпотентной записи: ключ записи — хеш транзакции и индекс события, поэтому повторная обработка диапазона не создаёт дублей. Журнал прогонов хранит границы каждого диапазона и его статус, так что любой участок можно переиграть точечно, не перезапуская конвейер целиком.
Эффект измерим на трёх метриках: время сбора исторического периода, доля потерянных записей и число отказов из-за лимитов. Первая падает в разы за счёт параллельного чтения, вторая уходит к нулю — пропуск виден по журналу, а не по расхождению итогов. Сверка адресов и балансов перестаёт быть разовым аудитом и идёт по расписанию.
Способы сбора данных: публичный интерфейс, своя нода, архив
Выбор способа доступа определяет не только скорость разработки, но и то, какие вопросы к данным вообще можно задать. Публичный программный интерфейс провайдера закрывает типовые сценарии за считанные дни, но ставит в зависимость от чужих лимитов и состава методов. Собственная нода даёт контроль над запросами и историей, зато требует ресурсов на синхронизацию и сопровождение.
Ключевая развилка — нужна ли глубина истории. Свежие блоки и текущие балансы отдаёт почти любой источник, а состояние на произвольной высоте прошлого доступно только там, где хранится архив блоков: обычный узел обрезает старые состояния, и часть запросов просто не выполняется. Поэтому источники чаще комбинируют: публичный интерфейс — для оперативных задач, архив — для аналитики и сверки.
| Способ | Когда подходит | Ограничения |
|---|---|---|
| Публичный программный интерфейс провайдера | Первые версии продукта, кошельковые сценарии, отслеживание свежих транзакций | Лимиты запросов, неполная история, состав методов и глубина меняются по решению провайдера |
| Потоковые подписки провайдера | Мониторинг событий в реальном времени и реакция на них | Прошлое недоступно, разрыв соединения нужно догонять отдельным проходом по истории |
| Собственная нода | Независимость от чужих лимитов, свои правила индексации | Длительная первичная синхронизация, растущий объём хранилища, постоянное сопровождение |
| Архив блоков на своей ноде | Аналитика, аудит, запросы состояния на любую высоту | Хранилище растёт заметно быстрее обычного узла, выше требования к оборудованию |
| Свой слой агрегации поверх архива | Сложные выборки, отчёты и метрики по собственным правилам | Нужна поддержка силами команды, расхождения с данными сторонних источников приходится сверять |
Ограничения провайдеров стоит проверять до старта: какие методы доступны, какова глубина истории, как сервис ведёт себя под пиковой нагрузкой и предупреждает ли об изменениях. Мы фиксируем это в схеме источников — чтобы переход на свою ноду был плановым шагом, а не аварийным.
Этапы внедрения: от аудита задач до передачи в поддержку
Порядок работ одинаков и для одной сети, и для мультисетевого контура: сначала фиксируем, что именно нужно читать из цепи, затем описываем потоки и только потом разворачиваем инфраструктуру. Так исключаем ситуацию, когда узел уже поднят и синхронизирован, а данные не сходятся с эксплорером.
- Аудит источников данных. Какие сети, контракты и типы событий нужны, что отдаёт публичный API, где есть лимиты на частоту запросов и какова доступная глубина истории. На выходе — перечень источников с их ограничениями.
- Схема потоков. Разделяем, что читаем напрямую из узла, а что из API, где стоит промежуточное хранилище и как обрабатывается перестройка цепи. Схему согласуем до начала разработки.
- Развёртывание и настройка. Поднимаем полный или архивный узел, настраиваем индексацию, очереди и повторные попытки при сбоях. Запись делаем идемпотентной, чтобы повторный проход не дублировал события.
- Проверка сверкой. Сравниваем выгрузку с эталоном — эксплорером или вторым независимым источником, сверяем контрольные суммы по блокам и итоговые балансы. Любое расхождение разбираем до запуска.
- Нагрузка и отказоустойчивость. Прогоняем на исторической глубине, проверяем поведение при недоступности узла и восстановление после обрыва, фиксируем время догона после простоя.
- Передача в эксплуатацию. Отдаём регламенты, панель мониторинга с оповещениями об отставании, инструкции для дежурного и обучение команды. Дальше — гарантийное сопровождение: донастраиваем граничные случаи и остаёмся на связи.
Схемы, политики доступа и регламенты: что остаётся в контуре
Контур парсинга ценен не тем, что работает сегодня, а тем, что его можно воспроизвести и починить чужими руками. Поэтому в передачу входят не только сервисы, но и артефакты: конфигурации, схемы и правила, по которым система живёт после запуска.
- Карта источников — какие данные откуда берутся: публичные интерфейсы эксплореров, собственные узлы, резервные провайдеры, и что чем подменяется при отказе.
- Схемы потоков — путь события от блока до хранилища и витрин: где нормализация, где дедупликация, где повторы запросов, где может потеряться порядок.
- Конфигурации узла — сети, глубина хранения, лимиты соединений, режим индексации и пояснение, что меняется при росте нагрузки.
- Политики доступа — роли сервисов, ключи, сетевые правила, права на чтение и запись, отдельно порядок отзыва доступов.
- Регламент реакции на сбои — таблица «симптом → проверка → действие»: отставание индексации, разрыв в цепочке, недоступность провайдера, расхождение данных.
- Метрики и пороги — какие сигналы считаются нормой, какие аварийными, кому и куда уходит оповещение.
- Инструкции по эксплуатации — как развернуть контур с нуля, как переиндексировать участок истории, как подключить новую сеть.
С этим набором команда заказчика добавляет сеть или меняет провайдера по инструкции, не разбирая архитектуру заново.
Кейс: убрали простои и ускорили сверку данных в разы
Заказчик — сервис аналитики по сети Ethereum — собирал историю через публичные интерфейсы эксплореров, то есть обычный парсинг блокчейн-эксплореров. На пиках нагрузки запросы упирались в лимиты, при перестройке цепочки часть блоков терялась, и в базе появлялись разрывы и дубли. Доля потерянных записей доходила до 6–7%, а расхождения с сетью находили только вручную — примерно 30 сверок в месяц, каждая на выгрузках.
Собрали собственный конвейер: своя нода как источник, поток блоков и событий, запись по ключу «высота блока + адрес события» — поэтому повторная обработка диапазона не создаёт дублей. При перестройке цепочки диапазон перечитывается автоматически, сбойные запросы уходят в повтор с нарастающей паузой, а отставание от головы цепочки видно на графике и поднимает оповещение до того, как данные начнут расходиться.
Добавили автоматическую сверку: контрольные суммы по диапазонам сопоставляются с независимым источником, расхождения раскладываются по типам — пропуск, дубль, неверное поле. Ручных сверок стало 1–2 в месяц вместо 30, и каждая занимает минуты: инженер смотрит отчёт о расхождениях, а не сравнивает сырые выгрузки.
Полный проход истории сократился с 14 часов до 40 минут за счёт параллельной обработки диапазонов и локального чтения вместо внешних запросов. Ушёл целый класс отказов: потери из-за лимитов публичных интерфейсов и «дыры» после перестройки сети. На живом потоке доля потерянных записей держится на нуле, а ежедневная выгрузка сходится с сетью без ручного вмешательства.
Чем публичный интерфейс отличается от собственной ноды
Публичный интерфейс — это чужая инфраструктура: кто-то другой держит копию цепочки и отдаёт вам данные по запросу. Своя нода — та же копия состояния, но у вас, и вы сами решаете, что и в каком объёме индексировать. Разница проявляется в трёх местах: глубина доступной истории, поведение потока под нагрузкой и то, где рвётся связь при сбое.
По глубине публичные шлюзы почти всегда отдают только недавнее окно блоков и событий — глубокие запросы отклоняются или обрезаются по диапазону. Архивный узел у вас хранит историю с первого блока, поэтому пересчёт метрик за прошлые периоды и восстановление пропущенных событий не упирается в чужое ограничение. Именно это определяет, можно ли достроить индекс задним числом или данные придётся собирать только вперёд.
Под нагрузкой публичный интерфейс вводит лимиты на частоту обращений, отвечает с переменной задержкой и разным качеством у разных операторов шлюза. Своя нода ограничена диском и сетью, а не чужим лимитом: параллелизм запросов, размер пакета и глубину кэша вы задаёте сами и видите, во что упираетесь.
Публичный шлюз — внешняя точка отказа: смена условий, переиндексация на чужой стороне или деградация узла останавливают сбор без вашего участия. Своя нода переносит ответственность внутрь: нужны контроль отставания от головы цепочки, обработка реорганизаций и идемпотентная запись, чтобы повторный проход не задваивал события. Выбор обычно не бинарный: публичный интерфейс закрывает разведку и разовые задачи, своя нода — регулярный сбор с полной историей.
Что уточняют перед стартом: лимиты, история, отказы
Прежде чем строить схему разбора, инженеры фиксируют границы доступных данных: какие внешние сервисы отдают историю, по какому лимиту запросов, докуда она простирается назад и насколько полна. Без этой инвентаризации конвейер наполняется до первого упора в лимит или обнаруживает провал в глубине уже на этапе аналитики. Ниже — сомнения, которые чаще всего всплывают на этом шаге.
Внешний сервис меняет лимиты или закрывает доступ — что тогда?
Лимиты внешних сервисов не константа: их снижают, вводят платные уровни, иногда отключают старые методы. Поэтому доступ инкапсулируется в отдельный слой адаптеров — смена источника или лимита не трогает логику обработки. Плюс мы всегда закладываем свой источник данных как резервный путь.
Доступной глубины истории не хватит для наших задач?
Публичные интерфейсы обычно отдают не всю цепочку, а окно от нескольких месяцев до пары лет. Если нужны более ранние состояния, поднимаем собственную ноду и вычитываем блоки последовательно либо добираем недостающий отрезок из архивных источников. Решение принимается по конкретному горизонту, а не «на всякий случай».
Как убедиться, что данные полные и без пропусков?
Проверка полноты строится на сверке: непрерывность номеров блоков, совпадение контрольных сумм по выборке, сходимость агрегатов с независимым источником. Расхождения логируются отдельно, а не растворяются в общем потоке — так пропуск виден сразу, а не через месяц в отчёте.
Можно ли начать с малого и расширяться?
Да, и это правильный порядок. Сначала один контракт или один тип событий, отладка на нём, затем поэтапное расширение охвата — новые сети, токены, исторические периоды. Каждый шаг добавляется без переписывания предыдущего, поэтому объём хранения растёт предсказуемо и остаётся под контролем.
Обсудим задачу: что нужно от вас для оценки и плана
Чтобы вернуться с оценкой и планом, нам нужен не общий замысел, а вводные по данным и инфраструктуре. Ниже — чеклист: если часть пунктов пока не определена, зафиксируем допущения и уточним их на этапе проектирования, а не в середине работ.
- Какие сети и сущности нужны: транзакции, переводы токенов, внутренние вызовы, события контрактов, балансы — и в каком виде отдавать их наружу.
- Откуда берём данные: публичные API эксплореров, провайдеры с готовой индексацией или собственная нода с полным архивом.
- Объёмы и частота обновления: глубина истории, поток новых блоков, допустимое запаздывание и окно пересчёта.
- Схема хранения и выборок: где храним, кто читает, по каким ключам строим запросы, какой объём держим горячим.
- Доступы и роли: ключи к API, учётные данные нод, права на запись в хранилище, кто с вашей стороны подтверждает изменения.
- Правила достоверности: как сверяем пропуски и расхождения при реорганизациях цепочки, что считаем эталонным источником.
- Режим выдачи: разовый срез, постоянный поток или регулярные пересчёты; нужен ли повторный проигрыш и откат.
Опишите задачу в свободной форме и приложите то, что уже есть, — обсудим варианты решения. Дальше вернёмся с оценкой и планом работ: этапы, сроки, состав проверок и точки, где потребуется ваше подтверждение.







