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

# Хранение и доказательства

> Как зафиксированное состояние сохраняется в трёх хранилищах RocksDB, аутентифицируется версионированным деревом Меркла и аккумуляторами и со временем обрезается.

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

Поэтому хранение разделяет задачу между отдельными хранилищами, каждое из которых заточено под свой шаблон доступа.

<h2 id="three-stores">
  Три хранилища
</h2>

<div className="dg" data-dg="storage-stores">
  <div className="dg-c" style={{aspectRatio:"720 / 332"}}>
    <svg className="dg-w" viewBox="0 0 720 332" aria-hidden="true">
      <path className="dg-wire dg--green dg-dash" d="M 434.00 48.00 L 459.60 48.00" />

      <path className="dg-head dg--green" d="M 466.00 48.00 L 459.60 52.40 L 459.60 43.60 Z" />

      <path className="dg-wire dg--green dg-dash" d="M 434.00 144.00 L 459.60 144.00" />

      <path className="dg-head dg--green" d="M 466.00 144.00 L 459.60 148.40 L 459.60 139.60 Z" />

      <path className="dg-wire dg--green dg-dash" d="M 434.00 240.00 L 459.60 240.00" />

      <path className="dg-head dg--green" d="M 466.00 240.00 L 459.60 244.40 L 459.60 235.60 Z" />

      <path className="dg-wire dg--blue dg-soft" d="M 135.00 144.00 L 172.54 53.91" />

      <path className="dg-head dg--blue" d="M 175.00 48.00 L 176.60 55.60 L 168.48 52.22 Z" />

      <path className="dg-wire dg--blue dg-soft" d="M 135.00 144.00 L 168.60 144.00" />

      <path className="dg-head dg--blue" d="M 175.00 144.00 L 168.60 148.40 L 168.60 139.60 Z" />

      <path className="dg-wire dg--blue dg-soft" d="M 135.00 144.00 L 172.54 234.09" />

      <path className="dg-head dg--blue" d="M 175.00 240.00 L 168.48 235.78 L 176.60 232.40 Z" />
    </svg>

    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"31.3253%",width:"18.0556%",height:"24.0964%"}}><span className="dg-t">Зафиксированный блок</span></div>
    <div className="dg-b dg--sky dg-left" style={{left:"25.0000%",top:"2.4096%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Хранилище реестра</span><span className="dg-s">транзакции · выходные данные · события · наборы записей · аккумуляторы · метаданные</span></div>
    <div className="dg-b dg--green" style={{left:"65.2778%",top:"2.4096%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Воспроизведение и аудит</span></div>
    <div className="dg-b dg--sky dg-left" style={{left:"25.0000%",top:"31.3253%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Хранилище состояния</span><span className="dg-s">текущие и исторические значения, шестнадцать шардов, горячее — в своём ярусе</span></div>
    <div className="dg-b dg--green" style={{left:"65.2778%",top:"31.3253%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Запросы и исполнение</span></div>
    <div className="dg-b dg--sky dg-left" style={{left:"25.0000%",top:"60.2410%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Хранилище Меркла</span><span className="dg-s">версионированное разреженное дерево Меркла и индексы вытесненных узлов</span></div>
    <div className="dg-b dg--green" style={{left:"65.2778%",top:"60.2410%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Проверка — доказательства</span></div>
    <div className="dg-free" style={{left:"0.0000%",top:"89.1566%",width:"100.0000%"}}><div className="dg-n">Чтение, которому нужно только значение, не платит за обход дерева, а доказательство не собирается заново из хранилища для точечных выборок.</div></div>
  </div>
</div>

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

**Хранилище состояния** держит значения состояния, адресуемые по ключу и версии. Именно его читают исполнение и запросы. Оно **разбито на шестнадцать шардов**, поэтому записи одного блока расходятся по шестнадцати независимым экземплярам RocksDB, а не конкурируют за один. Часто используемое состояние дополнительно держится в собственном ярусе, чтобы рабочий набор активного рынка не приходилось искать среди всего, что блокчейн когда-либо сохранил.

**Хранилище Меркла** держит аутентифицирующую структуру: узлы дерева, позволяющие доказать значение, и индексы, отслеживающие, какие узлы были вытеснены.

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

<h2 id="authentication">
  Аутентификация
</h2>

Две структуры Меркла делают разную работу.

<div className="dg" data-dg="storage-proofs">
  <div className="dg-c" style={{aspectRatio:"720 / 400"}}>
    <svg className="dg-w" viewBox="0 0 720 400" aria-hidden="true">
      <path className="dg-wire" d="M 173.50 98.50 L 173.50 110.10" />

      <path className="dg-head" d="M 173.50 116.50 L 169.10 110.10 L 177.90 110.10 Z" />

      <path className="dg-wire" d="M 173.50 169.00 L 173.50 180.60" />

      <path className="dg-head" d="M 173.50 187.00 L 169.10 180.60 L 177.90 180.60 Z" />

      <path className="dg-wire" d="M 173.50 239.50 L 173.50 251.10" />

      <path className="dg-head" d="M 173.50 257.50 L 169.10 251.10 L 177.90 251.10 Z" />

      <path className="dg-wire" d="M 546.50 122.00 L 546.50 133.60" />

      <path className="dg-head" d="M 546.50 140.00 L 542.10 133.60 L 550.90 133.60 Z" />

      <path className="dg-wire" d="M 546.50 216.00 L 546.50 227.60" />

      <path className="dg-head" d="M 546.50 234.00 L 542.10 227.60 L 550.90 227.60 Z" />
    </svg>

    <div className="dg-band" style={{left:"0.0000%",top:"6.5000%",width:"48.1944%",height:"72.5000%"}}><span className="dg-cap">Версионированное разреженное дерево Меркла</span></div>
    <div className="dg-band" style={{left:"51.8056%",top:"6.5000%",width:"48.1944%",height:"72.5000%"}}><span className="dg-cap">Аккумуляторы</span></div>
    <div className="dg-b dg--blue" style={{left:"2.2222%",top:"12.5000%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">Ваш ключ и его значение</span></div>
    <div className="dg-b" style={{left:"2.2222%",top:"30.1250%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">хеш-сосед</span></div>
    <div className="dg-b" style={{left:"2.2222%",top:"47.7500%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">хеш-сосед</span></div>
    <div className="dg-b dg--green" style={{left:"2.2222%",top:"65.3750%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">Корень состояния — фиксирует консенсус</span></div>
    <div className="dg-b dg--blue" style={{left:"54.0278%",top:"12.5000%",width:"43.7500%",height:"17.0000%"}}><span className="dg-t">Ваша транзакция или событие</span></div>
    <div className="dg-b" style={{left:"54.0278%",top:"36.0000%",width:"43.7500%",height:"17.0000%"}}><span className="dg-t">Аккумулятор транзакций · аккумулятор событий</span><span className="dg-s">каждый фиксирует всё включённое до сих пор, по порядку</span></div>
    <div className="dg-b dg--green" style={{left:"54.0278%",top:"59.5000%",width:"43.7500%",height:"17.0000%"}}><span className="dg-t">Корень реестра — фиксирует консенсус</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"0.0000%",top:"83.0000%",width:"100.0000%",height:"14.5000%"}}><span className="dg-s">Дерево доказывает, каким было значение; аккумуляторы — что произошло и в каком порядке. Вместе они позволяют доказать «эта транзакция есть в блокчейне на этой позиции», не имея самого блокчейна.</span></div>
  </div>
</div>

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

**Аккумуляторы** аутентифицируют последовательность. Один накапливает транзакции, другой — события, и каждый выдаёт корень, который фиксирует всё включённое до этого момента, и притом в порядке включения. Именно это позволяет доказать утверждение «эта транзакция находится в блокчейне на этой позиции», не имея самого блокчейна.

Вместе: дерево состояния доказывает, *каким было значение*, аккумуляторы — *что произошло и в каком порядке*.

<h3 id="speculative-state">
  Спекулятивное состояние
</h3>

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

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

<h3 id="caching">
  Кеширование
</h3>

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

<h2 id="pruning">
  Обрезка истории
</h2>

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

Обрезчики Меркла и значений состояния управляются **индексами устаревания**, которые пишутся одновременно с самими данными. Когда версия вытесняет узел или значение, вытесненная запись отмечается устаревшей на этой версии. Тогда обрезка — это сканирование диапазона по индексу, а не поиск мусора: что и когда станет пригодным к удалению, отмечено уже в момент записи.

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

<h2 id="backup-and-restore">
  Резервное копирование и восстановление
</h2>

Хранилища можно резервировать и восстанавливать независимо от работающего узла. Именно поэтому узел можно поднять из снимка, а не воспроизводить с генезиса, и сверить состояние восстановленного узла с зафиксированными корнями, а не доверять резервной копии.

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

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

  <Card title="Модель состояния" href="/ru/protocol/architecture/state/model">
    Что именно хранится и какое представление — источник истины.
  </Card>

  <Card title="Индексатор" href="/ru/protocol/architecture/indexer">
    Восстановление истории по зафиксированным записям.
  </Card>

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