Коррекция метки времени банка

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

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

Общая схема предлагаемой реализации выглядит следующим образом:

Исправление метки времени

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

Вычисление медианной временной метки, взвешенной по доле

Чтобы рассчитать предполагаемую временную метку для конкретного банка, среде выполнения сначала необходимо получить самые последние временные метки голосования из активного набора валидаторов. Метод Bank::vote_accounts() предоставляет состояние учетных записей для голосования, и они могут быть отфильтрованы для всех учетных записей, чья самая последняя метка времени была предоставлена ​​в течение последней эпохи.

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

Из этого набора выбирается медианная отметка времени, взвешенная по доле, то есть отметка времени, при которой 50% доли оценивают отметку времени больше или равно, а 50% доли оценивают отметку времени меньше или равно. как потенциальная исправленная временная метка.

Эта медианная отметка времени, взвешенная по доле, предпочтительнее взвешенного среднего, потому что умножение доли на предложенную отметку времени при расчете среднего позволяет узлу с очень маленькой долей по-прежнему оказывать большое влияние на результирующую отметку времени, предлагая отметку времени, которая очень большой или очень маленький. Например, используя предыдущий метод calculate_stake_weighted_timestamp(), узел с 0,00003% ставки, предлагающий метку времени i64::MAX, может сдвинуть метку времени вперед на 97 тысяч лет!

Ограничивающие временные метки

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

Это предложение предполагает, что каждая временная метка может отклоняться до 25% от ожидаемого времени с начала эпохи.

Чтобы рассчитать отклонение метки времени, каждый банк должен зарегистрировать epoch_start_timestamp в системной переменной Clock. Это значение устанавливается равным Clock::unix_timestamp в первом слоте каждой эпохи.

Затем среда выполнения сравнивает ожидаемое прошедшее время с начала эпохи с предполагаемым прошедшим временем на основе скорректированной метки времени. Если скорректированное прошедшее время находится в пределах +/- 25% от ожидаемого, скорректированная метка времени принимается. В противном случае оно ограничивается допустимым отклонением.