Надежная передача голоса

Голоса валидатора — это сообщения, которые имеют критическую функцию для достижения консенсуса и непрерывной работы сети. Поэтому крайне важно, чтобы они были надежно доставлены и закодированы в реестре.

Проблемы

  1. Ротация лидера запускается PoH, т.е. часами с большим дрейфом. Так много узлов, вероятно, будут иметь неправильное представление о том, активен ли следующий лидер в реальном времени или нет.
  2. Следующий лидер может быть легко затоплен. Таким образом, DDOS будет препятствовать не только доставке обычных транзакций, но и согласованным сообщениям.
  3. UDP ненадежен, и наш асинхронный протокол требует повторной передачи любого передаваемого сообщения до тех пор, пока оно не будет обнаружено в реестре. Повторная передача потенциально может вызвать непреднамеренное громкое стадо против лидера с большим количеством валидаторов. В худшем случае флуд будет (num_nodes * num_retransmits).
  4. Отслеживание того, был ли голос передан или нет через реестр, не гарантирует, что он появится в подтвержденном блоке. Текущий наблюдаемый блок может быть развернут. Валидаторы должны будут поддерживать состояние для каждого голосования и форка.

Дизайн

  1. Отправляйте голоса как push-сообщение через сплетни. Это обеспечивает передачу голоса всем следующим лидерам, а не только следующему будущему.
  2. Лидеры прочитают таблицу Crds на наличие новых голосов и закодируют любые новые полученные голоса в блоки, которые они предлагают. Это позволяет включать голоса валидаторов в вилки отката всеми будущими лидерами.
  3. Валидаторы, получившие голоса в леджере, добавят их в свою локальную таблицу crds не как push-запрос, а просто добавят их в таблицу. Это сокращает протокол push-сообщений, поэтому сообщения проверки не нужно дважды повторно передавать по сети.
  4. CrdsValue для голосования должно выглядеть так: Votes(Vec<Transaction>)

Каждая транзакция голосования должна поддерживать «настенные часы» в своих данных. Стратегия слияния для голосов сохранит последние N наборов голосов, настроенных локальным клиентом. Для push/pull вектор проходится рекурсивно, и каждая транзакция рассматривается как отдельная CrdsValue со своими собственными локальными часами и подписью.

Сплетни предназначены для эффективной пропаганды государства. Сообщения, отправляемые через gossip-push, группируются и распространяются с минимальным связующим деревом в остальную часть сети. Любые частичные сбои в дереве активно исправляются с помощью протокола gossip-pull, сводя к минимуму объем данных, передаваемых между любыми узлами.

Как этот дизайн решает проблемы

  1. Поскольку у валидаторов нет простого способа синхронизироваться с лидерами в «активном» состоянии лидера, сплетни допускают возможную доставку независимо от этого состояния.
  2. Gossip будет доставлять сообщения всем последующим лидерам, поэтому, если текущий лидер будет затоплен, следующий лидер уже получит эти голоса и сможет их закодировать.
  3. Gossip минимизирует количество запросов через сеть, поддерживая эффективное связующее дерево и используя фильтры Блума для восстановления состояния. Таким образом, отсрочка повторной передачи не требуется, и сообщения группируются.
  4. Лидеры, которые читают таблицу crds для голосов, будут кодировать все новые действительные голоса, которые появляются в таблице. Даже если блок этого лидера развернут, следующий лидер попытается добавить те же самые голоса без какой-либо дополнительной работы со стороны валидатора. Таким образом обеспечивается не только возможная доставка, но и возможная кодировка в реестр.

Представление

  1. В худшем случае время распространения до следующего лидера составляет Log(N) переходов с базой, зависящей от разветвления. С нашим текущим разветвлением по умолчанию, равным 6, это около 6 переходов на 20 тыс. узлов.
  2. Лидер должен получить 20 000 проверочных голосов, объединенных сплетнями в клочья размером с MTU. Что уменьшит количество пакетов для сети 20k до 80 фрагментов.
  3. Голоса каждого валидатора реплицируются по всей сети. Чтобы сохранить очередь из 5 предыдущих голосов, таблица Crds увеличилась бы на 25 мегабайт. (20 000 узлов * 256 байтов * 5).

Внедрение в два этапа

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

Сеть валидаторов Sub 1k

  1. Crds просто поддерживает последнее голосование валидатора.
  2. Голоса отправляются и повторно передаются независимо от того, появляются ли они в реестре.
  3. Разветвление 6.
  4. В худшем случае 256 КБ памяти на узел.
  5. В худшем случае 4 прыжка для распространения на каждый узел.
  6. Лидер должен получить весь набор голосов валидатора в 4 фрагментах push-сообщений.

Сеть ниже 20 тыс.

Все вышеперечисленное плюс следующее:

  1. Таблица CRDS поддерживает вектор из 5 последних голосов валидатора.
  2. Голоса кодируют настенные часы. CrdsValue::Votes — это тип, который рекурсивно входит в вектор транзакций для всех протоколов сплетен.
  3. Увеличьте разветвление до 20.
  4. В худшем случае 25 МБ памяти на узел.
  5. В наихудшем случае для доставки по всей сети требуется 4 прыжка.
  6. 80 клочков, полученных лидером за все сообщения валидатора.