Индексатор Ethereum: поиск и видимое отставание индексатора
Оглавление курса «Web3: вход, смарт-аккаунты и индексатор» · Урок 20 из 30.
Быстрый API каталога обычно читает проекцию индексатора, а не вызывает RPC для каждого посетителя. Такой ответ может отставать от сети. В этом уроке покажем происхождение и свежесть результата, добавим поиск по внешним названиям и не будем смешивать эти названия с полями контракта. Результат — читатель знает, до какого уровня обработана история и почему новое изменение ещё не видно.
Предполагаются checkpoint и пагинация. Поисковый сервер, база и программы не запускались. CourseCatalog содержит номер, отпечаток и активность, но не текст заголовка. Названия курсов приходят из проверенных манифестов или каталога сайта, поэтому их происхождение сохраняется отдельно.
Индексированный уровень
Ответ API включает indexedBlockNumber, indexedBlockHash, поколение и время последней успешной обработки. Дополнительно сервис может сохранить последнюю известную выбранную границу сети и показать разницу номеров. Это наблюдение head относится к своему времени, а не является постоянным обещанием текущего состояния сети.
Положительная разница высоты помогает оценить задержку, но не даёт точное время в секундах без модели конкретной сети. Локальная лаборатория может долго не создавать блоков, а потом создать несколько сразу. Поэтому не нужно переводить каждый блок в выдуманный постоянный интервал и показывать точное «отставание2минуты».
Время последнего успешного запроса тоже недостаточно: процесс мог быстро отвечать из старого checkpoint после отказа сохранения. Метрики чтения, commit и активной проекции разделяются. API показывает уровень действительно завершённой обработки, а не последний номер, который мелькнул в журнале отладки.
Собственный формат ответа
Ниже пример структуры для страницы курса17. Значения хешей представлены описательными обозначениями, не настоящими полученными результатами.
{
"course": { "id": "17", "active": true, "title": "Учебный реестр" },
"source": {
"chainId": "31337",
"environmentId": "library-lab-1",
"projectionGeneration": "generation-2",
"indexedBlockNumber": "205",
"indexedBlockHash": "BLOCK_HASH_FROM_CHECKPOINT",
"state": "ready"
},
"metadata": { "origin": "verified-release-manifest", "schemaVersion": 1 }
}
В настоящем API хеш имеет проверенную стандартную форму; обозначение в учебном листинге нельзя вставлять как валидное сетевое значение. title относится к внешнему манифесту, а active — к проекции событий. Такое разделение источников помогает при ошибке одной стороны не объявить все данные одинаково недостоверными.
Если заголовок манифеста не загружен, карточка может показать только номер. Она не придумывает красивое название по адресу или хешу. Когда файл доступен, схема и отпечаток проверяются по ранее объявленному правилу. Поиск по названию работает только в известном корпусе метаданных, а не во всех возможных материалах сети.
Поисковый запрос
Строка запроса ограничивается по длине и обрабатывается параметризованно. Не следует вставлять её в SQL или регулярное выражение без нужного правила. Серверная сессия не даёт права выполнять произвольный поиск по личной базе других читателей. Публичный каталог и персональные данные имеют разные endpoints и фильтры.
Для первой модели достаточно поиска по контролируемым заголовкам и номерам. Полнотекстовый индекс добавляется по отдельному источнику Markdown. Важно не обещать, что он отражает каждое последнее контрактное событие мгновенно. Связь версии манифеста с отпечатком выпуска определяет, какое содержание индексируется.
Неактивные выпуски могут оставаться в результатах истории, если такова политика каталога. Убирая их из текущего списка, сервис всё равно сохраняет старые URL материалов. Флаг учебного реестра не удаляет страницу ProfessorWeb автоматически. Веб-адреса и сетевой статус относятся к разным моделям проекта.
Отказ индексатора
При временном отказе RPC API может продолжать выдавать последнее завершённое поколение с отметкой stale или recovering. Скрывать эту отметку ради красивой карточки не следует. Посетитель понимает, что новое действие может ещё не отразиться. Для административной записи используется прямой актуальный маршрут подготовки, а не только поисковая проекция.
Если начальная история неполная, состояние ответа сообщает building и границы покрытия. Пустой поиск не доказывает отсутствия курса во всём реестре. Ограниченный корпус метаданных также обозначается. Это предотвращает ложное сообщение «материалов нет», когда проблема в подготовке источника.
В случае подтверждённой reorg активное поколение может временно остаться прежним с отметкой восстановления. Политика API определяет, выдавать ли такие данные или ограничить ответ. В любом варианте клиент не должен считать старую проекцию свежей по одному HTTP200. Статус источника является частью договора результата.
Кеширование ответа
Публичная проекция может кешироваться с учётом поколения и уровня. После переключения поколения ключ меняется или кеш инвалидируется. Если cachekey содержит только courseId17, ответ другой сети или прежней лаборатории может попасть в неправильную карточку. Контекст хранится на сервере и передаётся клиенту для ясности.
Персональный результат поиска или прогресса дополнительно связан с сессией и политикой кеширования. Его нельзя помещать в общий CDN-кеш как публичный каталог. Быстрый ответ не оправдывает утечку чужих данных. Граница прав сохраняется даже если приложение использует один удобный query-клиент в браузере.
Ожидаемое отображение
После новой публикации транзакционный экран может знать успешный receipt, а поисковая проекция ещё показывать прежний выпуск. Интерфейс объясняет разницу: операция исполнена, индексатор догоняет сеть. Он не откатывает зелёный receipt и не заменяет проекцию локальным аргументом без происхождения. После завершённого commit появляется новое поколение данных.
Для упражнения соедините успешную публикацию на блоке210 и API с checkpoint205. Назовите, что известно каждой части и какое сообщение получит человек. Затем выключите источник метаданных: номер и активность могут остаться, а поиск заголовков станет ограниченным. Итог — свежесть является наблюдаемым свойством источника, а не украшением интерфейса. Основы блоков и RPC описаны в Ethereum JSON-RPC.
Поиск по метаданным
Если название поступает из проверенного манифеста, рядом с поисковым документом сохраняем хеш материала и версию извлечения. Изменение названия после новой публикации курса требует переиндексации соответствующей записи. При недоступном манифесте можно оставить поиск по номеру курса и хешу, явно обозначив ограничение.
Результат «ничего не найдено» относится к покрытому срезу и доступным полям. Он не доказывает отсутствие курса во всей сети. Такая подпись особенно нужна при building или recovering, когда часть материала ещё не обработана.