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

# Мемпул

> Как транзакции допускаются, хранятся, упорядочиваются и распространяются до того, как консенсус зафиксирует их в блоке.

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

Для торговой сети это несущая конструкция, а не побочная деталь. Поток ордеров и отмен идёт всплесками, концентрируется у отдельных отправителей и чувствителен к задержке асимметрично: опоздавшая отмена хуже опоздавшего ордера. Описанные ниже структуры существуют потому, что одна очередь FIFO ни с чем из этого толком не справляется.

<h2 id="the-path-in">
  Путь внутрь
</h2>

<div className="dg" data-dg="mempool-admission">
  <div className="dg-c" style={{aspectRatio:"720 / 252"}}>
    <svg className="dg-w" viewBox="0 0 720 252" aria-hidden="true">
      <path className="dg-wire dg--blue" d="M 124.00 145.00 L 145.60 145.00" />

      <path className="dg-head dg--blue" d="M 152.00 145.00 L 145.60 149.40 L 145.60 140.60 Z" />

      <path className="dg-wire dg--orange" d="M 340.00 145.00 L 356.00 145.00 L 356.00 46.00 L 365.60 46.00" />

      <path className="dg-head dg--orange" d="M 372.00 46.00 L 365.60 50.40 L 365.60 41.60 Z" />

      <path className="dg-wire dg--sky" d="M 340.00 145.00 L 365.60 145.00" />

      <path className="dg-head dg--sky" d="M 372.00 145.00 L 365.60 149.40 L 365.60 140.60 Z" />

      <path className="dg-wire dg--sky dg-soft" d="M 541.00 145.00 L 566.40 120.45" />

      <path className="dg-head dg--sky" d="M 571.00 116.00 L 569.46 123.61 L 563.34 117.28 Z" />

      <path className="dg-wire dg--sky dg-soft" d="M 541.00 145.00 L 566.55 171.40" />

      <path className="dg-head dg--sky" d="M 571.00 176.00 L 563.39 174.46 L 569.71 168.34 Z" />
    </svg>

    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"46.8254%",width:"16.6667%",height:"21.4286%"}}><span className="dg-t">Подписанная транзакция</span></div>
    <div className="dg-b dg--yellow" style={{left:"21.6667%",top:"42.8571%",width:"25.0000%",height:"29.3651%"}}><span className="dg-t">Валидация</span><span className="dg-s">подпись · формат · состояние счёта · платёжеспособность</span></div>
    <div className="dg-b dg--orange dg-left" style={{left:"52.2222%",top:"7.9365%",width:"47.7778%",height:"20.6349%"}}><span className="dg-t">Отброшена с причиной</span><span className="dg-s">не молча — отправителю сообщают причину</span></div>
    <div className="dg-b dg--sky" style={{left:"52.2222%",top:"46.8254%",width:"22.2222%",height:"21.4286%"}}><span className="dg-t">Хранилище транзакций</span></div>
    <div className="dg-b dg--sky" style={{left:"80.0000%",top:"36.5079%",width:"20.0000%",height:"19.0476%"}}><span className="dg-t">Рассылка пирам</span></div>
    <div className="dg-b dg--sky" style={{left:"80.0000%",top:"60.3175%",width:"20.0000%",height:"19.0476%"}}><span className="dg-t">Сборка пакетов, затем консенсус</span></div>
    <div className="dg-free" style={{left:"0.0000%",top:"85.7143%",width:"100.0000%"}}><div className="dg-n">Валидация дешёвая и локальная, поэтому дорогие ресурсы дальше по цепочке тратятся только на транзакции, которые могли бы исполниться.</div></div>
    <div className="dg-lbl" style={{left:"49.4444%",top:"36.5079%"}}>отклонена</div>
    <div className="dg-lbl" style={{left:"49.4444%",top:"51.9841%"}}>принята</div>
  </div>
</div>

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

<h2 id="how-transactions-are-held">
  Как хранятся транзакции
</h2>

Принятые транзакции не лежат одной плоской очередью. Хранилище поддерживает несколько представлений над одним и тем же набором, и каждое отвечает на свой вопрос.

<div className="dg" data-dg="mempool-views">
  <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-soft" d="M 195.00 148.00 L 245.00 36.00" />

      <path className="dg-wire dg-soft" d="M 195.00 148.00 L 245.00 92.00" />

      <path className="dg-wire dg-soft" d="M 195.00 148.00 L 245.00 148.00" />

      <path className="dg-wire dg-soft" d="M 195.00 148.00 L 245.00 204.00" />

      <path className="dg-wire dg-soft" d="M 195.00 148.00 L 245.00 260.00" />
    </svg>

    <div className="dg-b dg--blue dg-round" style={{left:"0.0000%",top:"31.0241%",width:"26.3889%",height:"27.1084%"}}><span className="dg-t">Один набор принятых транзакций</span><span className="dg-s">пять представлений, а не пять очередей</span></div>
    <div className="dg-b dg--sky" style={{left:"34.7222%",top:"3.0120%",width:"65.2778%",height:"15.6627%"}}><span className="dg-t">Порядок по счетам</span><span className="dg-s">Какая транзакция у этого отправителя следующая?</span></div>
    <div className="dg-b dg--sky" style={{left:"34.7222%",top:"19.8795%",width:"65.2778%",height:"15.6627%"}}><span className="dg-t">Индекс приоритета</span><span className="dg-s">Что из всех отправителей предложить консенсусу первым?</span></div>
    <div className="dg-b dg--sky" style={{left:"34.7222%",top:"36.7470%",width:"65.2778%",height:"15.6627%"}}><span className="dg-t">Индекс сроков</span><span className="dg-s">У чего истёк срок?</span></div>
    <div className="dg-b dg--sky" style={{left:"34.7222%",top:"53.6145%",width:"65.2778%",height:"15.6627%"}}><span className="dg-t">Индекс таймлайна</span><span className="dg-s">О чём этот пир ещё не слышал?</span></div>
    <div className="dg-b dg--yellow" style={{left:"34.7222%",top:"70.4819%",width:"65.2778%",height:"15.6627%"}}><span className="dg-t">Отстойник</span><span className="dg-s">Что оформлено верно, но пока не годно?</span></div>
    <div className="dg-free" style={{left:"0.0000%",top:"89.1566%",width:"100.0000%"}}><div className="dg-n">Именно на отстойнике видны ошибки интеграции: валидная транзакция, которая пока не следующая у своего отправителя, отправляется в отстойник, а не отклоняется, — и становится годной, как только закроется дыра перед ней.</div></div>
  </div>
</div>

| Представление         | На какой вопрос отвечает                               |
| --------------------- | ------------------------------------------------------ |
| **Порядок по счетам** | Какая транзакция у этого отправителя следующая?        |
| **Индекс приоритета** | Что из всех отправителей предложить консенсусу первым? |
| **Индекс сроков**     | У чего истёк срок и что пора удалить?                  |
| **Индекс таймлайна**  | О чём этот пир ещё не слышал?                          |
| **Отстойник**         | Что корректно оформлено, но пока не годно к включению? |

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

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

<h2 id="dissemination-and-fairness">
  Распространение и справедливость
</h2>

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

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

<h2 id="handoff-to-consensus">
  Передача в консенсус
</h2>

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

Следствие: предложение блока несёт дайджесты пакетов, а не тела транзакций, поэтому размер сообщений консенсуса не растёт вместе с пропускной способностью, — а зафиксированный блок всегда воспроизводим, потому что данные за ним были доказуемо доступны ещё до того, как на них сослались. Как формируется и используется это доказательство — см. [IntentionBFT](/ru/protocol/architecture/intention-bft).

<Note>
  Поэтому же допуск в мемпул — не то же самое, что включение. Транзакция, которая принята, сохранена и разослана, вошла в очередь; упорядочена она не была. Ничего в судьбе транзакции не решено, пока консенсус не зафиксирует блок, в который она попала.
</Note>

<h2 id="what-this-means-for-a-client">
  Что это значит для клиента
</h2>

* **Отклонение при отправке информативно.** Оно произошло до того, как транзакцию сохранили, и его причина описывает то, что клиент может исправить.
* **Молчание — не отклонение.** Транзакция может стоять в отстойнике за дырой, которую клиент создал сам. Отслеживайте, что отправлено и что зафиксировано, а не считайте, что отсутствие подтверждения означает потерю.
* **Порядок внутри счёта важен, порядок между счетами — нет.** У двух транзакций от одного отправителя есть заданная последовательность. Две транзакции от разных отправителей упорядочивает консенсус, а не то, кто отправил первым.
* **У отмен нет привилегий в мемпуле.** Приоритет отмены — свойство [исполнения ядра](/ru/protocol/architecture/kernel), где отмены идут раньше агрессивных выставлений в том же блоке, а не свойство очереди.
