# Leased Proof of Stake (LPoS)
Любой блокчейн должен обладать механизмом консенсуса, который позволяет независимым нодам согласовывать данные между собой и обеспечивает целостность данных — то есть гарантирует, что все ноды в сети имеют одинаковую копию блокчейна и что все транзакции валидны.
Важной частью механизма консенсуса является алгоритм, который определяет, кто из участников сети имеет право выпустить следующий блок, а в случае возникновения нескольких альтернативных цепочек блоков — какая из них является основной. Этот алгоритм должен быть справедливым к участникам и устойчивым к атакам.
В протоколе Waves используется алгоритм консенсуса Leased Proof of Stake (LPoS), который является разновидностью Proof of Stake (PoS). Как и в других видах Proof of Stake, шанс участника сети сгенерировать следующий блок растет с количеством токенов системы на его балансе. В отличие от Proof of Work, Proof of Stake — экологичный алгоритм, который не требует больших вычислительных мощностей и затрат электроэнергии. Владельцы токенов системы заинтересованы в сохранении и увеличении их ценности, а значит — в поддержании безопасности сети.
Особенность протокола Leased Proof of Stake — в том, что обычные пользователи могут участвовать в генерации блоков, передавая токены в лизинг генерирующим нодам. При этом токены остаются под полным контролем владельца токенов: он может в любой момент отменить лизинг. Ноды могут выплачивать лизингодателям часть вознаграждения, полученного в результате генерации блоков. Подробнее о лизинге
# Основные принципы Waves LPoS
- Шанс получить возможность выпустить блок пропорционален генерирующему балансу ноды.
- Чтобы нода могла принять участие в генерации блоков, ее генерирующий баланс должен быть не менее 1000 WAVES.
- Генерирующий баланс рассчитывается как наименьший баланс в WAVES с учетом лизинга за последние 1000 блоков, чтобы исключить манипуляции процессом генерации блоков путем перемещения средств между аккаунтами.
- Выбор генератора следующего блока непредсказуем, чтобы исключить манипуляции путем атаки на генератора или намеренного пропуска возможности создания блока.
- Средний интервал между блоками подгоняется к 60 секундам.
# Выбор генератора блока
Каждая генерирующая нода i при получении очередного, (n – 1)-го блока по сети рассчитывает временную задержку Ti,n, которую она должна выждать, прежде чем получит право сгенерировать n-й блок. Задержка рассчитывается на основе генерирующего баланса ноды и времени между блоками, с использованием псевдослучайного числа — подробнее об этом ниже.
Если другой генератор выпустил свой блок раньше и нода i получила n-й блок до того, как сгенерировала свой, процесс начинается заново: рассчитывается время Ti,n+1, и нода ожидает, когда наступит ее время сгенерировать (n + 1)-й блок.
# VRF
VRF (Verifiable Random Function) — псевдослучайная функция создания криптографического хеша. Только владелец закрытого ключа может вычислить хеш, но кто угодно может проверить правильность хеша с помощью открытого ключа. Использование VRF делает выбор генератора блока непредсказуемым из-за необходимости знать закрытый ключ для расчета.
Реализация VRF содержит функцию signVRF
, которая вычисляет хеш некоторого сообщения с закрытым ключом аккаунта:
proof = signVRF(message, privateKey),
и функцию verifyVRF
, которая проверяет предоставленный хеш с помощью сообщения и открытого ключа аккаунта и возвращает детерминированное значение VRF
:
VRF = verifyVRF(proof, message, public key).
# generationSignature
generationSignature
(генерирующая подпись, сигнатура генерации) — параметр блока, который рассчитывается с использованием значения VRF
на 100 блоков ранее и закрытого ключа генератора блока:
generationSignaturen = signVRF(VRFn – 100, privateKeyn),
VRFn = verifyVRF(generationSignaturen, VRFn – 100, publicKeyn).
Первые 8 байт VRF
n, взятые в обратном порядке, преобразуются в число Xi,n, которое называется хитом и используется как случайное число для расчета временной задержки. Достоверность вычисления хита можно проверить с помощью функции verifyVRF
. В то же время хит невозможно предсказать до публикации generationSignature
n, для вычисления которой требуется закрытый ключ генератора.
# Временная задержка
Временная задержка в миллисекундах, которую i-й аккаунт должен выждать после генерации (n – 1)-го блока, прежде чем он сможет сгенерировать n-й блок, рассчитывается по следующей формуле:
где
- Tmin = 15 000 мc — константа, устанавливающая минимальный временной интервал между блоками;
- C1 = 70 — константа, устанавливающая форму распределения интервала между блоками;
- C2 = 517 — константа, корректирующая значение
baseTarget
; - Xi,n — хит, полученный из
VRF
n-го блока; - Xmax = 264 – 1 — максимально возможный хит (8-байтное число);
- bi,n — генерирующий баланс i-го аккаунта в WAVELET;
- Λn —
baseTarget
n-го блока, адаптивный коэффициент, регулирующий среднее время выпуска блока.
# baseTarget
baseTarget
— параметр блока, который корректирует среднее время между блоками, приближая его к 60 секундам. baseTarget
одинаков для всех генераторов, пытающихся создать n-й блок, и зависит от среднего времени Tavg выпуска трех предшествующих блоков (n – 3, n – 2, n – 1):
- если Tavg > 90 c, то Λn = Λn-1 + max(1, Λn-1/100);
- если Tavg < 30 c и Λn-1 > 1, то Λn = max(1, Λn-1 – max(1, Λn-1/100));
- в остальных случаях Λn = Λn-1.
# Выбор основной цепочки
Для выбора лучшей цепочки блоков используется параметр score
. Score
блока равен 264 / baseTarget
, а score
цепочки — это сумма score
всех ее блоков. В случае возникновения форка — нескольких альтернативных цепочек — выбирается цепочка с наибольшим score
.
Более подробно, ноды рассылают друг другу score
своих цепочек. Если нода А обнаруживает, что у ноды B score
цепочки больше, она выясняет, может ли она переключиться на ту цепочку. Для этого нода A отправляет ноде B идентификаторы 100 последних блоков своей цепочки.
Если нода B находит среди них блок, который есть и у нее, то отправляет ноде A идентификатор наибольшего общего блока, а также ID всех последующих блоков своей цепочки.
Далее нода A удаляет блоки своей цепочки вплоть до общего блока, запрашивает у ноды B новые блоки по ID и применяет их.
# История развития протокола
Изначально сеть Waves использовала модель Proof of Stake, предложенную Nxt.
В июле 2018 года, с активацией фичи № 8 “Fair PoS”, формулы PoS были скорректированы, чтобы сделать выбор генератора блока справедливым и снизить уязвимость к атакам. Подробнее о Fair PoS
В сентябре 2020 года, с активацией фичи № 15 “Ride V4, VRF, Protobuf, Failed transactions”, был реализован способ вычисления generationSignature
с помощью VRF, чтобы сделать выбор генератора блока непредсказуемым. Подробнее о переходе на VRF