Skip to main content
Часть того, что площадке нужно знать о счёте, невозможно посчитать во время исполнения блока. Уровень по объёму зависит от тридцати дней торгов. Вознаграждение зависит от окна, которое ещё не закрылось. Реферальная привязка зависит от связи, установленной месяцы назад. Затащить эту работу внутрь исполнения блока было бы ошибкой сразу по двум причинам: каждый блок платил бы за расчёт, который почти ни одному блоку не нужен, а ядру пришлось бы нести историю, которую ему больше незачем хранить. Программные сервисы решают это, разворачивая направление. Расчёт идёт вне блока, поверх зафиксированной записи. Его результат затем фиксируется обратно в блокчейне как состояние протокола, откуда исполнение читает его за константное время, как любую другую конфигурацию.
Зафиксированная история торгов
Программный сервисрасчёт по окну, вне блокачитает таблицу комиссий из блокчейна
Изменилось с прошлого применения?
Ничего не пишется
Транзакция протокола
Состояние блокчейна
Чтение при исполненииза константное время
Сравнение по ставкам, а не по позициямСдвиг порога или переоценка уровня меняют то, сколько счёт платит, не меняя индекса его уровня.
Итоговую ставку определяет блокчейнПериод отмечается применённым только после фиксации каждого пакета; падение приводит к повтору всего периода — это безопасно, потому что расчёт идемпотентный.
Источником истины остаётся блокчейн. Сервис не хранит состояние, от которого зависит сеть, — он предлагает значение, и реально только то, что блокчейн принял.

Что работает сегодня

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

Модель отказов

Эти сервисы стоят между двумя системами, каждая из которых иногда будет недоступна. Конструкция исходит из этого, а не считает это исключением. Отказы зависимостей — базы данных, потока от узла, API узла — обрабатываются повторными попытками с нарастающей задержкой. Процесс от них не завершается: перезапуск не чинит недоступную зависимость, он лишь добавляет к простою холодный старт. Фатальным остаётся то, что перезапуск починить может или что оператор обязан увидеть: неверная конфигурация при старте, невозможность поднять эндпоинт проверки состояния и паники. Во время сбоя процесс продолжает работать, сообщает о себе «не готов» и считает ошибки. Поэтому эксплуатационный сигнал — это «не готов уже N минут», а не «процесс жив». Полезен именно первый вопрос: живой процесс, который час не может ничего принять, — это и есть настоящий инцидент. На сигналы оркестратора процесс завершается корректно: работа останавливается, контрольные точки сбрасываются на диск, процесс выходит чисто. Без этого каждое рутинное развёртывание стоило бы несохранённого окна и повторного расчёта.
Период, который посчитан, но ещё не применён, — не потерянный период. Расчёт идемпотентный, а период отмечается применённым только после успешной записи, поэтому прерванный запуск возобновляется повтором окна, а не пропускает его.

Почему этот паттерн обобщается

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

Что дальше

Индексатор

Поток, который потребляют эти сервисы.

Комиссии

Коммерческая сторона: какие есть уровни и сколько они стоят.

IntentionKernel

Как записанная обратно конфигурация читается во время исполнения.

Модель состояния

Почему ключи конфигурации версионируются и почему клиентам стоит читать их вживую.