> ## 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.

# Синхронизация состояния

> Как узел, никогда не видевший блокчейна, доходит до текущей версии и как он на ней удерживается.

Узлу, входящему в сеть, надо ответить на два вопроса: как добраться туда, где блокчейн сейчас, и как там удержаться. Синхронизация состояния отвечает на оба, и компромисс между ними сделан явно, а не спрятан.

<h2 id="two-modes-of-catching-up">
  Два способа догнать сеть
</h2>

Начальная загрузка — выход на текущую версию с нуля — делается одним из двух принципиально разных способов.

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

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

<div className="dg" data-dg="state-sync">
  <div className="dg-c" style={{aspectRatio:"720 / 322"}}>
    <svg className="dg-w" viewBox="0 0 720 322" aria-hidden="true">
      <path className="dg-wire dg--blue" d="M 134.00 126.00 L 159.60 126.00" />

      <path className="dg-head dg--blue" d="M 166.00 126.00 L 159.60 130.40 L 159.60 121.60 Z" />

      <path className="dg-wire dg--sky" d="M 324.00 126.00 L 356.54 75.38" />

      <path className="dg-head dg--sky" d="M 360.00 70.00 L 360.24 77.76 L 352.84 73.00 Z" />

      <path className="dg-wire dg--yellow" d="M 324.00 126.00 L 356.54 176.62" />

      <path className="dg-head dg--yellow" d="M 360.00 182.00 L 352.84 179.00 L 360.24 174.24 Z" />

      <path className="dg-wire dg--green" d="M 568.00 70.00 L 578.66 119.74" />

      <path className="dg-head dg--green" d="M 580.00 126.00 L 574.36 120.66 L 582.96 118.82 Z" />

      <path className="dg-wire dg--green" d="M 568.00 182.00 L 578.66 132.26" />

      <path className="dg-head dg--green" d="M 580.00 126.00 L 582.96 133.18 L 574.36 131.34 Z" />
    </svg>

    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"30.4348%",width:"18.0556%",height:"17.3913%"}}><span className="dg-t">Новый узел</span></div>
    <div className="dg-b dg--yellow dg-round" style={{left:"23.6111%",top:"29.1925%",width:"20.8333%",height:"19.8758%"}}><span className="dg-t">Режим начальной загрузки</span></div>
    <div className="dg-b dg--sky" style={{left:"50.5556%",top:"6.2112%",width:"27.7778%",height:"31.0559%"}}><span className="dg-t">Воспроизвести историю</span><span className="dg-s">выполнить заново или применить сохранённое, с генезиса</span><span className="dg-n">медленно, и с каждым днём медленнее</span></div>
    <div className="dg-b dg--yellow" style={{left:"50.5556%",top:"40.9938%",width:"27.7778%",height:"31.0559%"}}><span className="dg-t">Скачать текущее состояние</span><span className="dg-s">ключи и значения на последней версии, с проверкой по корню</span><span className="dg-n">актуально за долю времени</span></div>
    <div className="dg-b dg--green" style={{left:"81.1111%",top:"25.4658%",width:"18.8889%",height:"27.3292%"}}><span className="dg-t">Текущая версия</span><span className="dg-s">далее непрерывная синхронизация</span></div>
    <div className="dg-b dg--orange dg-left" style={{left:"0.0000%",top:"78.2609%",width:"100.0000%",height:"18.0124%"}}><span className="dg-t">Пути не равнозначны</span><span className="dg-s">Узел, скачавший текущее состояние, не может обслуживать исторические запросы и сказать, как позиция пришла в своё состояние. Узлу для индексатора или аудита нужна пропущенная история.</span></div>
  </div>
</div>

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

<Note>
  Это эксплуатационное решение, а не умолчание, которое принимают не думая. Узел, скачавший текущее состояние, не может обслуживать исторические запросы и не может ответить, как позиция пришла в своё нынешнее состояние: истории для чтения у него нет. Узлу, обслуживающему [индексатор](/ru/protocol/architecture/indexer) или процесс аудита, нужна ровно та история, которую он пропустил.
</Note>

<h2 id="staying-current">
  Как остаться на текущей версии
</h2>

Выйдя на текущую версию, узел держится на ней, потребляя зафиксированные блоки по мере их поступления, — снова либо выполняя транзакции, либо применяя выходные данные, с тем же разменом: строгость проверки против скорости.

Отличие от начальной загрузки в том, что разрыв малый и постоянный, а не большой и сокращающийся. Узел, отставший достаточно сильно, снова уходит на путь начальной загрузки, а не пытается закрывать произвольный разрыв по кусочкам.

<h2 id="how-data-moves">
  Как движутся данные
</h2>

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

| Слой                          | Роль                                                                                                       |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------- |
| **Сервис хранения**           | Отдаёт данные другим узлам: транзакции, выходные данные, значения состояния и сопутствующие доказательства |
| **Клиент данных**             | Выбирает пиров, отслеживает, у кого что есть, отправляет запросы и разбирается с теми, что не удались      |
| **Сервис потоковой передачи** | Превращает «доставь меня отсюда туда» в упорядоченный поток проверенных фрагментов                         |
| **Драйвер**                   | Решает, что узлу нужно дальше, и применяет то, что приходит                                                |

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

<h2 id="verification">
  Проверка
</h2>

В синхронизации состояния ничто не принимается на основании того, кто это прислал.

Значения состояния сверяются с зафиксированным корнем состояния. Транзакции и выходные данные — с аккумуляторами. Узел, который закончил начальную загрузку, получает состояние с корнем, совпадающим с тем, что подписал кворум валидаторов. Именно это делает быстрый путь безопасным: скачивание текущего состояния пропускает историю, но не пропускает проверку.

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

<CardGroup cols={2}>
  <Card title="Хранение и доказательства" href="/ru/protocol/architecture/state/storage">
    Структуры, благодаря которым синхронизация проверяема.
  </Card>

  <Card title="Запуск узла" href="/ru/developers/run-a-node">
    Роли узлов и как спросить о запуске своего.
  </Card>

  <Card title="Топология сети" href="/ru/protocol/architecture/intention-bft">
    С каким ярусом узлов разговаривает синхронизирующийся пир.
  </Card>

  <Card title="Индексатор" href="/ru/protocol/architecture/indexer">
    На какие вопросы отвечает история и не может ответить текущее состояние.
  </Card>
</CardGroup>
