Перейти к основному содержимому

Контракты управления

warning

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

В TON параметры консенсуса работы узла, связанные с TVM, catchain, комиссиями и топологией цепи (а также то, как эти параметры хранятся и обновляются), контролируются набором специальных смарт-контрактов – в отличие от устаревших и негибких способов хардкода этих параметров, принятых в блокчейнах предыдущих поколений. Таким образом, TON реализует всеобъемлющее и прозрачное on-chain управление. Сам набор специальных смарт-контрактов регулируется параметрами, и в настоящее время включает в себя контракты Избирателя, Конфигурации, и DNS, а в будущем будет расширен за счет extra-currency Minter и др.

Избиратель

Смарт-контракт Elector (Избиратель) управляет тем, как раунды валидации сменяют друг друга, кто получает обязанность валидировать блокчейн и как будет распределяться вознаграждение за валидацию. Если вы хотите стать валидатором и взаимодействовать с избирателем, ознакомьтесь с инструкциями валидатора.

Избиратель хранит данные о невыведенных Toncoin в хешмапе credits, новые заявки – в хешмапе elect, а информацию о предыдущих выборах – в хешмапе past*elections, последняя хранится внутри complaints (жалоб на неправильную работу валидатора) и frozen-stakes* (замороженных ставок валидатора за уже завершенные раунды, которые удерживаются stake_held_for(ConfigParam 15)). Контракт Избирателя выполняет следующие задачи:

  • Обработка заявок для проведения выборов валидаторов
  • Проведение выборов
  • Обработка отчетов о неправильной работе валидатора
  • Распределение вознаграждений за валидацию

Обработка заявок

Чтобы создать заявку, будущий валидатор должен сформировать специальное сообщение, содержащее соответствующие параметры (адрес ADNL, публичный ключ, max_factor и т.д.), прикрепить его к некоторой сумме TON (называемой ставкой) и отправить Избирателю. Избиратель, в свою очередь, проверяет эти параметры и либо регистрирует заявку, либо сразу же возвращает ставку обратно отправителю. Обратите внимание, что заявки принимаются только с адресов на мастерчейне.

Проведение выборов

Избиратель – это специальный смарт-контракт, который имеет возможность принудительно вызываться в начале и в конце каждого блока (так называемые Tick и Tock транзакции). Избиратель, действительно, вызывается на каждом блоке и проверяет, не пора ли провести новые выборы.

Общая концепция процесса выборов состоит в том, чтобы рассмотреть все заявки, в частности, их сумму TON и max_factor (максимальное соотношение работы по проверке, которую этот заявитель согласен выполнить, по сравнению с самым слабым валидатором), и установить веса для каждого валидатора пропорционально сумме TON, но таким образом, чтобы все условия max_factor были выполнены.

Технически это реализовано следующим образом:

  1. Избиратель принимает все заявки с суммой ставки, превышающей текущий сетевой минимум min_stake (ConfigParam 17).
  2. Происходит сортировка заявок по ставке в порядке убывания.
  3. Если участников больше, чем максимальное количество валидаторов (max_validators ConfigParam 16), список сокращается с конца.
  4. Выполняется цикл i от 1 до N (среди оставшихся участников):
  • Берется первый i-элемент из списка (отсортированного в порядке убывания),
  • Исходя из того, что i-ый кандидат будет принят последним (и, следовательно, имеет наименьший вес), рассчитывается эффективная ставка (true_stake) относительно max_factor. Другими словами, эффективная ставка j-го заявителя (j<i) рассчитывается как min(stake[i]*max_factor[j], stake[j]),
  • Вычисляется общая эффективная ставка (TES – total effective stake) участников с 1-го по i-й. Если данная TES выше, чем предыдущая известная максимальная TES, то она считается наилучшей текущей весовой конфигурацией.
  1. Получение текущей наилучшей конфигурации, т.е. весовой конфигурации, которая использует максимальную ставку, и ее отправка в контракт конфигурации (Config contract), чтобы она стала новым набором валидаторов.
  2. Внесение всех неиспользованных ставок, например, ставок от заявителей, которые не стали валидаторами, и излишков, если таковые имеются stake[j]-min(stake[i]*max_factor[j], stake[j]) в таблицу credits, откуда они могут быть запрошены заявителями.

Таким образом, если у нас есть девять кандидатов со 100 000 TON и коэффициентом 2,7 и один участник с 10 000 TON, то последний участник не будет избран: без него эффективная ставка составит 900 000 TON, а с ним – только 9 * 27 000 + 10 000 = 253 000 TON. Напротив, если у нас есть один кандидат со 100 000 TON и коэффициентом 2,7 и девять участников с 10 000 TON, все они станут валидаторами. Однако первый кандидат может поставить только 10 000 *2,7 = 27 000 TON, а излишек в 73 000 TON пойдет в credits.

Обратите внимание, что существуют некоторые ограничения (очевидно, контролируемые параметрами конфигурации TON) на результирующий набор валидации, в частности, min_validators, max_validators (ConfigParam 16), min_stake, max_stake, min_total_stake, max_stake_factor (ConfigParam 17). Если выполнить эти условия с помощью текущих заявок нет возможности, проведение выборов будет отложено.

Обработка отчетов о неправильной работе валидатора

Каждый валидатор время от времени случайным образом получает задание создать новый блок (если через несколько секунд валидатор не справляется, эта обязанность переходит к следующему валидатору). Частота таких назначений определяется весом валидатора. Таким образом, любой желающий может получить блоки из предыдущего раунда валидации и проверить, близко ли ожидаемое количество сгенерированных блоков к реальному количеству блоков. Статистически значимое отклонение (когда количество сгенерированных блоков меньше ожидаемого) означает, что валидатор ведет себя неправильно. В блокчейне TON относительно легко доказать неправильное поведение с помощью Merkle proofs (Меркл пруф). Контракт избирателя принимает такое доказательство с предложенным штрафом от любого, кто готов заплатить за его хранение, и регистрирует жалобу. Затем каждый валидатор текущего раунда проверяет жалобу, и если она верна и предложенный штраф соответствует серьезности ошибки, валидаторы голосует за нее. Получив более 2/3 голосов, жалоба принимается, а штраф удерживается из хешмап frozen соответствующего элемента past_elections.

Распределение вознаграждений за валидацию

Точно так же как и при проверке того, не пора ли проводить новые выборы, Избиратель в каждом блоке проверяет, не пора ли освободить средства из frozen за сохранённые past_elections. В соответствующем блоке Избиратель распределяет накопленный доход (сборы за газ и вознаграждения за создание блока) от соответствующих раундов валидации между валидаторами этого раунда пропорционально весам валидаторов. После этого ставки с вознаграждениями добавляются в таблицу credits, а информация о предыдущих выборах удаляется из таблицы past_elections.

Текущее состояние избирателя

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

Смарт-контракт Конфигурации

Смарт-контракт Config (Конфигурации) контролирует параметры конфигурации TON. Его логика определяет, кто и при каких условиях имеет право изменять некоторые из этих параметров. Он также реализует механизм предложения/голосования и регулярное обновление набора валидаторов.

Регулярное обновление набора валидаторов

Как только контракт конфигурации получает специальное сообщение от контракта избирателя, уведомляющее о выборе нового набора валидаторов, контракт конфигурации помещает новый набор валидаторов в ConfigParam 36 (следующие валидаторы). Затем в каждом блоке во время TickTock-транзакций контракт проверяет пришло ли время применить новый набор валидаторов (время utime_since заложено в самом наборе валидаторов) и перемещает предыдущий набор из ConfigParam 34 (текущие валидаторы) в ConfigParam32 (предыдущие валидаторы), а наборы из ConfigParam 36 в ConfigParam 34.

Механизм предложения/голосования

Любой, кто готов заплатить за хранение предложения, может предложить изменить один или несколько параметров конфигурации, отправив соответствующие сообщения смарт-контракту конфигурации. В свою очередь, любой валидатор из текущего набора может проголосовать за это предложение, подписав сообщение об одобрении своим приватным ключом (обратите внимание, что соответствующий публичный ключ хранится в ConfigParam 34). Набрав или не набрав 3/4 голосов (с учетом веса валидаторов), предложение выигрывает или проигрывает раунд. При выигрыше критического количества раундов (min_wins ConfigParam 11) предложение принимается, при проигрыше критического количества раундов (max_losses ConfigParam 11) оно отклоняется. Обратите внимание, что некоторые параметры считаются критическими (набор критических параметров сам является параметром конфигурации ConfigParam 10) и, таким образом, требуют большего количества раундов для принятия.

Индексы параметров конфигурации -999, -1000, -1001 зарезервированы для голосования за механизм экстренного обновления и обновления кода контрактов конфигурации и избирателя. Когда предложение с соответствующими индексами набирает достаточное количество голосов в достаточном количестве раундов, соответствующих аварийному ключу, код контракта конфигурации или код контракта избирателя обновляется.

Экстренное обновление

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

Валидаторы действительно проголосовали за назначение этого ключа TON Foundation в июле 2021 года (блок мастерчейна 12958364). Обратите внимание, что такой ключ может быть использован только для ускорения обновления конфигурации. Он не может вмешиваться в код, хранение и баланс любого контракта на любой цепочке.

История экстренных обновлений:

  • 17 апреля 2022 г. количество заявок на участие в выборах выросло настолько, что в тот момент выборы не могли быть проведены в соответствии с ограничениями на газ. В частности, для проведения выборов требовалось более 10 миллионов газа, в то время как блоки soft_limit и hard_limit были установлены на 10m и 20m (ConfigParam 22), special_gas_limit и block_gas_limit были установлены на 10m и 10m, соответственно (ConfigParam 20). Таким образом, новые валидаторы не могут сформироваться, т.к. из-за достижения лимита газа в блоке транзакции, обрабатывающей внутренние сообщения на мастерчейне, не могут быть включены в блок. В свою очередь, это привело к невозможности голосования за обновление конфигурации (невозможно было выиграть необходимое количество раундов, так как текущий раунд не мог завершиться). Аварийный ключ был использован для обновления ConfigParam 22 soft_limit до 22m и hard_limit до 25m (в блоке 19880281), а ConfigParam 20 special_gas_limit до 20m и block_gas_limit до 22m (в блоке 19880300). В результате выборы были успешно проведены, а следующий блок израсходовал 10 001 444 газа. Общая задержка выборов составила около 6 часов, при этом функциональность бейсчейн не пострадала.
  • 2 марта 2023 г. количество заявок на участие в выборах выросло настолько, что даже 20m не хватало для проведения выборов. Однако на этот раз мастерчейн продолжал обрабатывать внешние сообщения благодаря повышенному hard_limit. Аварийный ключ был использован для обновления ConfigParam 20 special_gas_limit до 25m и block_gas_limit до 27m (в блоке 27747086). В результате выборы были успешно проведены в следующем блоке. Общая задержка выборов составила около 6 часов, функциональность как мастерчейна, так и бейсчейна не пострадала (за исключением выборов).
  • 22 ноября 2023 г. ключ был использован для самоотзыва (в блоке 34312810). В результате открытый ключ был заменен на 32 нулевых байта.
  • В связи с переходом на OpenSSL-реализацию верификации подписи Ed25519, проверка на особый случай (все байты публичного ключа одинаковы) была отключена. В результате чего проверка на нулевой публичный ключ перестала работать так, как было задумано. Используя эту проблему, аварийный ключ был обновлен 9 декабря еще раз (в блоке 34665437, транзакция) до проверяемо случайной кривой 82b17caadb303d53c3286c06a6e1affc517d1bc1d3ef2e4489d18b873f5d7cd1 – sha256 (не является допустимой точкой кривой). Теперь единственный способ обновить параметры конфигурации сети – это механизм консенсуса валидатора.

См. также