Надежная передача голоса
Голоса валидатора — это сообщения, которые имеют критическую функцию для достижения консенсуса и непрерывной работы сети. Поэтому крайне важно, чтобы они были надежно доставлены и закодированы в реестре.
Проблемы
- Ротация лидера запускается PoH, т.е. часами с большим дрейфом. Так много узлов, вероятно, будут иметь неправильное представление о том, активен ли следующий лидер в реальном времени или нет.
- Следующий лидер может быть легко затоплен. Таким образом, DDOS будет препятствовать не только доставке обычных транзакций, но и согласованным сообщениям.
- UDP ненадежен, и наш асинхронный протокол требует повторной передачи любого передаваемого сообщения до тех пор, пока оно не будет обнаружено в реестре. Повторная передача потенциально может вызвать непреднамеренное громкое стадо против лидера с большим количеством валидаторов. В худшем случае флуд будет
(num_nodes * num_retransmits)
. - Отслеживание того, был ли голос передан или нет через реестр, не гарантирует, что он появится в подтвержденном блоке. Текущий наблюдаемый блок может быть развернут. Валидаторы должны будут поддерживать состояние для каждого голосования и форка.
Дизайн
- Отправляйте голоса как push-сообщение через сплетни. Это обеспечивает передачу голоса всем следующим лидерам, а не только следующему будущему.
- Лидеры прочитают таблицу Crds на наличие новых голосов и закодируют любые новые полученные голоса в блоки, которые они предлагают. Это позволяет включать голоса валидаторов в вилки отката всеми будущими лидерами.
- Валидаторы, получившие голоса в леджере, добавят их в свою локальную таблицу crds не как push-запрос, а просто добавят их в таблицу. Это сокращает протокол push-сообщений, поэтому сообщения проверки не нужно дважды повторно передавать по сети.
- CrdsValue для голосования должно выглядеть так:
Votes(Vec<Transaction>)
Каждая транзакция голосования должна поддерживать «настенные часы» в своих данных. Стратегия слияния для голосов сохранит последние N наборов голосов, настроенных локальным клиентом. Для push/pull вектор проходится рекурсивно, и каждая транзакция рассматривается как отдельная CrdsValue со своими собственными локальными часами и подписью.
Сплетни предназначены для эффективной пропаганды государства. Сообщения, отправляемые через gossip-push, группируются и распространяются с минимальным связующим деревом в остальную часть сети. Любые частичные сбои в дереве активно исправляются с помощью протокола gossip-pull, сводя к минимуму объем данных, передаваемых между любыми узлами.
Как этот дизайн решает проблемы
- Поскольку у валидаторов нет простого способа синхронизироваться с лидерами в «активном» состоянии лидера, сплетни допускают возможную доставку независимо от этого состояния.
- Gossip будет доставлять сообщения всем последующим лидерам, поэтому, если текущий лидер будет затоплен, следующий лидер уже получит эти голоса и сможет их закодировать.
- Gossip минимизирует количество запросов через сеть, поддерживая эффективное связующее дерево и используя фильтры Блума для восстановления состояния. Таким образом, отсрочка повторной передачи не требуется, и сообщения группируются.
- Лидеры, которые читают таблицу crds для голосов, будут кодировать все новые действительные голоса, которые появляются в таблице. Даже если блок этого лидера развернут, следующий лидер попытается добавить те же самые голоса без какой-либо дополнительной работы со стороны валидатора. Таким образом обеспечивается не только возможная доставка, но и возможная кодировка в реестр.
Представление
- В худшем случае время распространения до следующего лидера составляет Log(N) переходов с базой, зависящей от разветвления. С нашим текущим разветвлением по умолчанию, равным 6, это около 6 переходов на 20 тыс. узлов.
- Лидер должен получить 20 000 проверочных голосов, объединенных сплетнями в клочья размером с MTU. Что уменьшит количество пакетов для сети 20k до 80 фрагментов.
- Голоса каждого валидатора реплицируются по всей сети. Чтобы сохранить очередь из 5 предыдущих голосов, таблица Crds увеличилась бы на 25 мегабайт.
(20 000 узлов * 256 байтов * 5)
.
Внедрение в два этапа
Первоначально сеть может надежно работать только с одним голосом, передаваемым и поддерживаемым через сеть с текущей реализацией Vote. Для небольших сетей достаточно разветвления 6. В небольшой сети память и накладные расходы незначительны.
Сеть валидаторов Sub 1k
- Crds просто поддерживает последнее голосование валидатора.
- Голоса отправляются и повторно передаются независимо от того, появляются ли они в реестре.
- Разветвление 6.
- В худшем случае 256 КБ памяти на узел.
- В худшем случае 4 прыжка для распространения на каждый узел.
- Лидер должен получить весь набор голосов валидатора в 4 фрагментах push-сообщений.
Сеть ниже 20 тыс.
Все вышеперечисленное плюс следующее:
- Таблица CRDS поддерживает вектор из 5 последних голосов валидатора.
- Голоса кодируют настенные часы. CrdsValue::Votes — это тип, который рекурсивно входит в вектор транзакций для всех протоколов сплетен.
- Увеличьте разветвление до 20.
- В худшем случае 25 МБ памяти на узел.
- В наихудшем случае для доставки по всей сети требуется 4 прыжка.
- 80 клочков, полученных лидером за все сообщения валидатора.