> ## Documentation Index
> Fetch the complete documentation index at: https://docs.intention.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Индексатор

> Как зафиксированные блоки становятся данными для запросов: потоковый путь от полного узла до интерфейсов REST и WebSocket.

Блокчейн фиксирует блоки. Приложения задают вопросы вроде *какие исполнения были у этого счёта на прошлой неделе* и *как выглядит стакан прямо сейчас* — на такие вопросы запись в форме блока отвечает плохо. Индексатор переводит одно в другое.

В большинстве блокчейнов индексатор — критичный элемент инфраструктуры: блокчейн выпускает непрозрачные события, а смысл из них восстанавливают третьи стороны, поэтому то, во что верит ваше приложение, зависит от того, какому индексатору оно доверяет. Здесь шага восстановления просто нет. [Ядро](/ru/protocol/architecture/kernel) выдаёт типизированные выходные данные с атрибуцией — каждое изменение состояния уже привязано к вызвавшей его транзакции, — поэтому индексатор переформатирует данные, а не домысливает их.

Это меняет назначение индексатора: он **слой отдачи данных**, а не источник истины. Всё, что он сообщает, можно сверить с блокчейном, и расхождение — это баг индексатора, а не открытый вопрос.

<h2 id="the-path">
  Путь
</h2>

<div className="dg" data-dg="indexer-path">
  <div className="dg-c" style={{aspectRatio:"720 / 318"}}>
    <svg className="dg-w" viewBox="0 0 720 318" aria-hidden="true">
      <path className="dg-wire dg--blue dg-soft" d="M 123.00 102.00 L 155.98 75.97" />

      <path className="dg-head dg--blue" d="M 161.00 72.00 L 158.70 79.42 L 153.25 72.51 Z" />

      <path className="dg-wire dg--blue dg-soft" d="M 123.00 102.00 L 156.23 131.73" />

      <path className="dg-head dg--blue" d="M 161.00 136.00 L 153.30 135.01 L 159.16 128.45 Z" />

      <path className="dg-wire dg--sky dg-soft" d="M 349.00 72.00 L 381.98 98.03" />

      <path className="dg-head dg--sky" d="M 387.00 102.00 L 379.25 101.49 L 384.70 94.58 Z" />

      <path className="dg-wire dg--sky dg-soft" d="M 349.00 136.00 L 382.23 106.27" />

      <path className="dg-head dg--sky" d="M 387.00 102.00 L 385.16 109.55 L 379.30 102.99 Z" />

      <path className="dg-wire dg--green" d="M 536.00 102.00 L 551.60 102.00" />

      <path className="dg-head dg--green" d="M 558.00 102.00 L 551.60 106.40 L 551.60 97.60 Z" />
    </svg>

    <div className="dg-band" style={{left:"20.8333%",top:"8.1761%",width:"29.1667%",height:"47.7987%"}}><span className="dg-cap">деление по возрасту</span></div>
    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"19.4969%",width:"16.3889%",height:"25.1572%"}}><span className="dg-t">Полный узел</span><span className="dg-s">зафиксированные блоки как типизированные записи</span></div>
    <div className="dg-b dg--sky" style={{left:"23.0556%",top:"14.4654%",width:"24.7222%",height:"16.3522%"}}><span className="dg-t">Кеш</span><span className="dg-s">свежее — из памяти</span></div>
    <div className="dg-b dg--sky" style={{left:"23.0556%",top:"34.5912%",width:"24.7222%",height:"16.3522%"}}><span className="dg-t">Файловое хранилище</span><span className="dg-s">история — долговременно</span></div>
    <div className="dg-b dg--sky" style={{left:"54.4444%",top:"19.4969%",width:"19.4444%",height:"25.1572%"}}><span className="dg-t">Сервис данных</span><span className="dg-s">подаёт оба как один поток</span></div>
    <div className="dg-b dg--green" style={{left:"78.0556%",top:"19.4969%",width:"21.9444%",height:"25.1572%"}}><span className="dg-t">Шлюз → REST · WebSocket</span><span className="dg-s">доступ, квоты, маршрутизация</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"0.0000%",top:"67.2956%",width:"48.8889%",height:"27.6730%"}}><span className="dg-t">Зачем это разделение</span><span className="dg-s">Слежение за головой чувствительно к задержке и невелико; исторические запросы велики и требуют пропускной способности. Одна дозагрузка по общему пути застопорила бы живой.</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"51.1111%",top:"67.2956%",width:"48.8889%",height:"27.6730%"}}><span className="dg-t">Слой отдачи данных, а не источник истины</span><span className="dg-s">Ядро выдаёт типизированные выходные данные с атрибуцией, поэтому индексатор переформатирует, а не домысливает. Расхождение с блокчейном — баг индексатора.</span></div>
  </div>
</div>

**Полный узел** — источник. Торговые записи вытекают из него потоком как типизированные данные, а не как сырые транзакции, требующие интерпретации.

**Кеш и файловое хранилище** делят поток по возрасту. Свежие данные отдаются из памяти, потому что именно их хочет большинство потребителей и потому что задержка важна. Историю пишут в долговременное файловое хранилище, потому что держать всё в памяти — не стратегия. Потребитель, спрашивающий что-то старое, и потребитель, идущий за головой цепочки, обслуживаются из разных мест, и ни один из них этого не замечает.

**Сервис данных** подаёт и то и другое как один поток. Клиент запрашивает диапазон начиная с любой точки; откуда этот диапазон отдаётся — из кеша, из файлов или из обоих источников — не его забота.

**Шлюз** берёт на себя то, чему место между сервисом и публичным интернетом: доступ, квоты и маршрутизацию.

**Интерфейсы REST и WebSocket** — то, чем приложения пользуются на самом деле: рыночные данные, история ордеров и исполнений, позиции, состояние счёта, платежи финансирования и живые подписки. Детали на уровне эндпоинтов — см. [справочник API](https://testnet-openapi.intention.xyz/).

<h2 id="why-the-split-exists">
  Зачем это разделение
</h2>

Один сервис, который и следовал бы за головой цепочки, и отвечал бы на исторические запросы, не делал бы хорошо ни того ни другого. Слежение за головой чувствительно к задержке и невелико по объёму; исторические запросы чувствительны к пропускной способности и велики, и одна крупная дозагрузка застопорила бы живой путь.

Разделение даёт вот что: дозагрузка нового потребителя данными многомесячной давности не портит поток маркет-мейкера, идущего за головой, и масштабировать эти два пути можно независимо — а это им нужно, потому что профили нагрузки у них не имеют ничего общего.

<h2 id="what-it-is-safe-to-rely-on">
  На что можно полагаться
</h2>

**Можно.** На всё, что индексатор отдаёт на основе зафиксированных блоков: исполнения, ордера, позиции, платежи финансирования, переводы, рыночные данные. Это переформатированные выходные данные блокчейна.

**Это другое.** Всё, что ещё не зафиксировано. Ордер, принятый в [мемпул](/ru/protocol/architecture/mempool), ещё не упорядочен, и индексатору о нём сказать нечего. Отсутствие в индексаторе означает «ещё не зафиксировано», а не «отклонено».

**Проверяемо.** Если ответ достаточно важен — спор по расчётам, аудит, бухгалтерская сверка, — его можно сверить напрямую с блокчейном, а не брать из индексатора. Самая сильная форма этого — запустить собственный полный узел; именно так и следует поступать участнику, которому нельзя ошибаться. См. [Запуск узла](/ru/developers/run-a-node).

<Note>
  Два потребителя, читающие один и тот же зафиксированный диапазон, должны получить один и тот же ответ. Если нет — расхождение сидит в пути отдачи данных, и о нём стоит сообщить как о баге, а не считать неизбежным свойством чтения блокчейна через индексатор.
</Note>

<h2 id="where-to-go-next">
  Что дальше
</h2>

<CardGroup cols={2}>
  <Card title="Модель состояния" href="/ru/protocol/architecture/state/model">
    Что читает индексатор и какое представление авторитетно.
  </Card>

  <Card title="Разработчикам" href="/ru/developers/overview">
    Интерфейсы REST и WebSocket, SDK и инструменты.
  </Card>

  <Card title="Запуск узла" href="/ru/developers/run-a-node">
    Как сверять с блокчейном самостоятельно и почему набор закрыт.
  </Card>

  <Card title="Программные сервисы" href="/ru/protocol/architecture/programs">
    Кто потребляет этот поток, чтобы вычислять производное состояние счетов.
  </Card>
</CardGroup>
