Коллатор

Коллация

Коллатор (Collator) - компонент валидатора Tycho, который детерминированно забирает входящие сообщения из модуля консенсуса, исполняет их и формирует блоки.

Назначение коллатора

Коллатор отвечает за:

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

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

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

Дедупликация входящих данных

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

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

Важно: дедупликация не используется как защита от повторного проигрывания сообщений (replay protection), так как эта защита реализована на уровне смарт-контрактов. Дедупликация внешних сообщений служит в первую очередь как оптимизация работы протокола.

Входные данные коллации

Для сборки блока коллатор использует три класса входных данных:

  • внешние сообщения из DAG-мемпула: коллатор получает детерминированно упорядоченную (по якорям) и предварительно дедуплицированную последовательность внешних сообщений, согласованную сетью на стадии DAG-мемпула;
  • внутренние сообщения из очередей: сообщения, порожденные контрактами, накапливаются во внутренних очередях и затем подаются на коллацию. Допускается детерминированная разбивка аккаунтов (а значит и их входящих сообщений) на независимые партиции, которые можно обрабатывать параллельно;
  • контекст состояния и конфигурации: предыдущее состояние шарда и актуальные данные мастерчейна и конфигурации сети.

Группировка сообщений для параллельного исполнения

Коллатор исполняет входящие сообщения не "сплошным потоком", а порциями - группами сообщений. Группа сообщений - это детерминированно сформированный набор сообщений, который коллатор передает на один шаг исполнения и обработки результатов.

Смысл такой группировки:

  • повысить параллелизм: группа собирается так, чтобы в ней было много независимых аккаунтов, которые можно исполнять одновременно на разных ядрах;
  • снизить конфликты и упростить параллельное исполнение: сообщения группируются по аккаунтам назначения, и один аккаунт представлен в группе сообщений только один раз (со своей очередью сообщений), что исключает конкуренцию за одно и то же состояние;
  • ограничить "взрыв" работы: группы формируются с лимитами на размер порции и на "емкость" отдельных частей порции, чтобы один аккаунт/очередь не мог непропорционально занять весь шаг исполнения;
  • обеспечить предсказуемость и детерминизм: правила отбора сообщений в группу должны быть полностью детерминированными, чтобы при одинаковом входе все валидаторы сформировали одинаковые группы и получили одинаковый результат.

Свойства группировки группами сообщений:

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

Выполнение сообщений

Коллатор выступает оркестратором исполнения сообщений на смарт-контрактах: он подбирает детерминированный набор сообщений для обработки, подготавливает контекст состояния и правил исполнения, запускает выполнение в VM через Executor и собирает результаты.

Executor удобно рассматривать как "чистую функцию" над состоянием и входными сообщениями: при фиксированном входе он детерминированно вычисляет результаты исполнения и новое состояние. Внутри этого процесса TVM исполняет байткод контрактов в sandbox-модели.

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

Детерминизм

Коллатор не может опираться на локальную, недетерминированную информацию (системное время, порядок прихода сетевых пакетов, текущую загрузку CPU/диска). Если такие данные влияют на выбор сообщений, группировку или точки синхронизации, разные валидаторы при одинаковом входе соберут разные блоки. Поэтому коллация построена на строгих правилах, которые дают один и тот же результат независимо от производительности сервера.

Детерминизм обеспечивается двумя аспектами:

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

Порядок исполнения фиксируется правилами логического времени:

  • последовательные сообщения одного аккаунта исполняются в строгом порядке по логическому времени;
  • между блоками сохраняется монотонность (сообщения более позднего блока считаются логически позже сообщений более раннего блока);
  • при отборе сообщений для очередного шага исполнения применяется детерминированная сортировка и детерминированные правила для взаимозависимых вызовов.

Синхронизация с DAG-мемпулом также не может строиться на "прошло N секунд". Вместо этого коллатор измеряет затраты на выпуск блоков в детерминированных единицах работы (Work Unit). Эти единицы считаются по фиксированным формулам фаз prepare, execute и finalize, а затем накапливаются в счетчике между якорями. Накопив достаточно Work Unit, коллатор импортирует следующие якоря и все честные валидаторы делают это после одного и того же номера блока, даже если их реальная скорость выполнения отличается.

Порог импорта задается on-chain параметром wu_used_to_import_next_anchor в CollationConfig. При высоком накопленном значении коллатор может импортировать несколько якорей подряд в одном цикле, последовательно уменьшая накопленный счетчик на один порог за каждый импорт. Подробный разбор формул и правил импорта приведен в Work Unit в Collator.

Создание блоков

Коллатор создает блок, повторяя детерминированный цикл: читает доступные внешние и внутренние сообщения, формирует группы сообщений, исполняет их, накапливает результаты и обновления состояния, после чего финализирует блок. На каждом шаге считаются Work Unit фаз prepare, execute и finalize, а их сумма попадает в счетчик между якорями. Если в системе есть невыполненные сообщения, коллатор выпускает блоки непрерывно, без простоя. Если входящей нагрузки нет (нет ни внешних, ни внутренних сообщений), пустые блоки создаются редко - в основном затем, чтобы внешние клиенты видели, что сеть не "стоит" и продолжает продвигать высоту/время.

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

Важный практический момент: в рамках коллации готовые блоки не передаются по сети валидаторам как "большие объекты". Тем не менее размер блока полезно ограничивать, чтобы не перегружать клиентов, которым нужно скачивать, индексировать и хранить данные. На практике такие ограничения формулируются как ограничение вычислительной работы в блоке, например через максимальный суммарно потраченный газ или максимальное число операций/шагов исполнения.

Верификация

Верификация в Tycho используется для:

  • Механизм самопроверки: валидатор сравнивает локально полученный результат коллации с тем, что подтверждают остальные участники. Это позволяет своевременно обнаружить устаревшую версию ноды.
  • Механизм сбора подписей для клиентов: подписи валидаторов позволяют лайт-нодам принимать блок без полной валидации "тяжелой" части (проверок консенсусного входа и повторного выполнения сообщений), что экономит их CPU/память/трафик и позволяет быстро индексировать транзакции в сети.
  • Логически отделенный этап: верификация опциональна относительно самого процесса консенсуса и коллации и может идти асинхронно, пока коллатор продолжает работу над следующими блоками.

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