Перевод статьи https://cexplorer.io/article/understanding-input-endorsers
В статье мы объясним, почему консенсусный алгоритм блокчейна первого поколения так мало масштабируется и в чем основная причина неэффективности. Далее мы покажем, как индоссанты входа включают элементы параллелизма в консенсус, сохраняя при этом линейность блокчейна.
Эффективное использование ресурсов
Распределенная сеть Cardano состоит из нод, которые предоставляют свои вычислительные ресурсы сети. Однако эти ресурсы неэффективно используются в текущей версии консенсуса с доказательством ставки Proof-of-Stake (PoS), поскольку он основан на алгоритме, который появился вместе с блокчейном первого поколения.
Сеть Cardano создает блок в среднем каждые 20 секунд. В течение этого периода времени каждый раз случайным образом выбирается один производитель блоков для создания нового блока. Все остальные ноды являются валидаторами блоков. Проверка (валидация) блока занимает примерно 50-100 миллисекунд.
Этот алгоритм можно рассматривать как пустую трату больших вычислительных мощностей и пропускной способности сети. Это приводит к тому, что процессоры нод большую часть времени простаивают, за исключением короткого периода, когда нода либо создает, либо проверяет блок. Использование доступных сетевых ресурсов “точечным” образом приводит к их недоиспользованию.
В описании мы пренебрегли ресурсами, необходимыми для решения битв слотов (за один период создается несколько блоков) и распространения транзакций.
Блокчейн сети первого поколения размещают валидные транзакции в мемпулах. Один раз за период один произвольно выбранный производитель блоков может взять только ограниченное количество транзакций и поместить их в блок. Размер блока ограничен, поэтому он может не соответствовать всем доступным транзакциям. Как только транзакции начинают оставаться в мемпуле, пользователям приходится ждать расчетов по своим транзакциям в течение более длительного времени.
Чем больше размер блока, тем дольше происходит распространение в сети. Блок должен достичь всех нод сети как можно быстрее, чтобы быть доступным в качестве родителя для нового блока.
Проще говоря, с помощью этого простого алгоритма консенсуса масштабируемость блокчейна определяется частотой создания блоков и его размером. Например, 90 килобайт каждые 20 секунд в случае Cardano или один мегабайт каждые 10 минут в случае Bitcoin.
На изображении ниже вы можете видеть время, разделенное на слоты (секунды). В сети Cardano в среднем каждые 20 секунд создается 1 новый блок. Ноды большую часть времени находятся в режиме ожидания (пустые слоты указывают на простаивающие ноды).
Сетевые ресурсы могли бы использоваться параллельно, но описанный выше алгоритм является последовательным. Использование последовательного алгоритма в параллельной системе обязательно приводит к неэффективному использованию ресурсов.
Блокчейн является линейным, поскольку каждый вновь добавленный блок строится на предыдущем блоке. Это является следствием того факта, что зависимости данных (особенно транзакций) также носят линейный характер во время проверки. Давайте покажем это на примере.
Как только средства (UTxO) с адреса A перемещаются (таким образом, расходуются) на адрес B в транзакции 1, мгновением позже те же средства не могут быть перемещены с адреса A на адрес C в транзакции 2. В леджер должна быть внесена только транзакция 1 или транзакция 2, но не обе сразу. В таком случае новые средства были бы созданы из ничего.
Распределенная сеть должна предотвращать атаки с двойным расходованием средств (попытку потратить средства дважды) децентрализованным образом. В настоящее время это достигается во многих блокчейн сетях с помощью последовательного алгоритма, описанного выше. Неэффективность проистекает из того факта, что пользователи используют сеть параллельно, то есть транзакции (и другие данные) появляются в сети непрерывно и параллельно.
Основной причиной низкой масштабируемости блокчейнов является использование последовательного алгоритма в сети, в которой данные генерируются пользователями параллельно и в относительно большом объеме (при более широком принятии ожидается рост объема данных). Последовательность применима только к созданию блоков. Проверка новых блоков может происходить параллельно.
Распределенная сеть может восприниматься как параллельная система с точки зрения пользователей (генераторов данных), но также и с точки зрения нод, которые могут работать по взаимному согласию в определенной степени независимо друг от друга (они обрабатывают данные). Другими словами, достижение единого глобального состояния требует синхронизации и обмена данными, которые осуществляются с использованием определенного объема данных. Если мы увеличиваем объем данных, на основе которых формируется консенсус, мы также повышаем масштабируемость.
Cardano использует модель учета, основанную на UTxO. Транзакции в леджерах UTxO открыто идентифицируют все свои входы и выходы заранее, и эти зависимости являются полными. Найти транзакции, которые конфликтуют друг с другом, несложно. Неконфликтующие транзакции в блоке могут быть переупорядочены, т.е. проверены в другом порядке или параллельно, независимо от результата проверки. Относительно легко создать доказуемо безопасный алгоритм, использующий параллелизм и распараллеливание таким образом, чтобы одновременно обеспечивать корректность данных в леджере.
Таким образом, возможно создать распределенный параллельный алгоритм, который будет обрабатывать транзакции одновременно. Это означает возможность обрабатывать транзакции и создавать блокчейн с того момента, как пользователи отправляют их в сеть.
Однако определенная линейность системы должна поддерживаться на уровне леджера из-за зависимостей транзакций. Алгоритм должен частично оставаться последовательным, поскольку структура блокчейна должна оставаться линейной (защита от атак с двойным расходованием).
Индоссанты входа предлагают новый распределенный алгоритм, позволяющий проводить параллельную проверку данных. Однако современные алгоритмы уже могут это делать. Кроме того, функция индоссантов входа позволит параллельно разрабатывать структуру блокчейна на более низком уровне, гарантируя при этом, что она остается линейной на более высоком уровне. Степень параллелизма в структуре блокчейна ограничена зависимостями транзакций.
Алгоритм индоссантов входа позволяет сети достигать как параллелизма, так и конкурентности, при обработке транзакций за счет использования нескольких типов блоков. Параллелизм означает, что несколько задач могут выполняться одновременно, в то время как конкурентность означает, что несколько задач могут выполняться в перекрывающийся период времени.
Функция индоссантов входа обеспечивает параллелизм, позволяя нескольким транзакциям быть проверенными и одобренными (будет объяснено позже) одновременно разными нодами. Она также обеспечивает конкурентность, позволяя создавать и распространять несколько блоков в каждом слоте. Различные типы блоков, такие как блоки ранжирования и блоки подтверждения (которые будут объяснены позже), могут быть созданы параллельно разными нодами, а затем отправлены производителям блоков для включения в леджер. Это может увеличить пропускную способность и производительность сети Cardano при сохранении надежных свойств безопасности.
Изменение алгоритма, т.е. использование конкурентности и параллелизма, является единственным способом увеличить масштабируемость блокчейна. Невозможно увеличить масштабируемость за счет уменьшения частоты создания блоков или увеличения размера блока, поскольку это скоро достигнет пределов (особенно при нынешних возможностях Интернета). Частичные корректировки, конечно, возможны, но всегда необходимо тщательно учитывать влияние всех атрибутов сети на качество. Кроме того, эти корректировки могут привести лишь к незначительному улучшению масштабируемости по сравнению с изменением алгоритма.
Изменение алгоритма позволит лучше использовать ресурсы, которые уже доступны для сети Cardano (1200 активных пулов). Более эффективное использование ресурсов обеспечит более высокую масштабируемость.
Функции индоссантов входа используют три типа блоков
Функция индоссантов входа использует 3 типа блоков: блоки входа (IB), блоки подтверждения, иначе блоки-индоссанты (EB), и блоки ранжирования (RB). Поскольку создание блоков в сети Cardano является случайным процессом, может случиться так, что некоторые типы блоков будут создаваться параллельно в одном слоте. Для каждого типа блоков будет установлена разная частота создания.
Чаще всего блоки входа будут создаваться в диапазоне от 0,2 до 2 секунд. Блоки подтверждения могут создаваться каждые 5-10 секунд. Блоки ранжирования будут выполнять ту же функцию, что и текущие блоки, и будут создаваться в течение 15-30 секунд. Точные частоты создания блоков в настоящее время неизвестны и, вероятно, будут скорректированы по мере необходимости. Можно ожидать, что вначале они будут установлены консервативно.
На изображении ниже вы можете увидеть возможную частоту создания всех типов блоков. Блоки входа (IB) создаются каждую секунду. Блоки подтверждения (EB) создаются раз в 5 секунд. Блоки ранжирования (RB) создаются раз в 20 секунд.
Случайно выбранная нода может сгенерировать блок входа в заданном слоте. Нода извлекает последовательность транзакций из своего мемпула. Эти транзакции должны быть действительны по отношению к текущему состоянию, т.е. к последнему блоку ранжирования (с точки зрения ноды, он должен быть последним). Как мы объясним далее, ранжирование блоков обеспечивает линейность блокчейна. Блоки входа создаются в соответствии с текущим состоянием леджера, т.е. по отношению к последнему блоку ранжирования.
Блоки входа ссылаются на последний (или недавний) блок ранжирования. С точки зрения корректности данных в леджера должна быть предусмотрена возможность добавления новых транзакций из блоков входа.
Назначение блоков входа состоит в том, чтобы передавать полезную нагрузку блокчейна, то есть в основном транзакции и сертификаты. Помимо последовательности транзакций, каждый блок входа также содержит ссылки на недавний блок ранжирования. Ссылка включена для того, чтобы было ясно, какое состояние леджера использовать для проверки транзакций в блоке входа. Транзакции внутри блока входа могут зависеть друг от друга.
На рисунке ниже вы можете видеть, что блоки входа созданы с учетом последнего блока ранжирования.
Обратите внимание, что каждую секунду одна нода в сети может опустошить весь свой мемпул, при условии, что транзакции вписываются во блок входа. Частота опустошения мемпула значительно выше, чем при использовании алгоритма консенсуса первого поколения.
Как только нода создает новый блок входа, она отправляет его в сеть другим нодам.
Как только другие ноды в сети получают блок входа, они могут проверить его (транзакция, подпись производителя блока, доказательство VRF и т.д.). Проверка выполняется в отношении текущего состояния леджера, которое должно соответствовать блоку ранжирования, который ссылается на входной блок.
Входные блоки генерируются в сети чаще всего (это может быть даже до 5 раз в секунду), поэтому они независимы друг от друга. Это означает, что ноды могут проверять их независимо друг от друга.
Ноды могут рандомно быть выбраны для создания блока подтверждения. Целью блоков подтверждения является ускорение согласования в сети относительно существования и действительности входных блоков.
Ноды подтверждения берут ссылки на все последние блоки входа, которые являются действительными и которые еще не были включены в другой блок подтверждения, и создают новый блок подтверждения. Ноды-индоссанты иногда также могут ссылаться на другие блоки подтверждения, если на них еще не было ссылок в блоке ранжирования. Для того чтобы ссылки были возможны, оба блока подтверждения должны быть совместимы друг с другом.
Давайте покажем это на примере. В момент времени T создается блок подтверждения EB-1, который ссылается на входной блок IB-1. В момент времени T+1 создается другой блок подтверждения EB-2, который ссылается на входной блок IB-2. Поскольку IB-1, так и IB-2 не имеют конфликтующих транзакций, поэтому EB-2 может ссылаться на EB-1 как на свой родительский блок. Таким образом, EB-2 становится дочерним блоком EB-1, и как EB-1, так и EB-2 совместимы друг с другом. Это позволяет создать древовидную структуру блоков подтверждения, где каждая ветвь представляет отдельный набор транзакций, которые могут быть включены в леджер через следующий блок ранжирования.
На изображении ниже вы можете видеть 3 блока подтверждения, которые ссылаются на несколько входных блоков. Последний блок подтверждения также ссылается на предыдущий блок подтверждения.
Подобно входным блокам, блоки подтверждения распространяются в сети таким же образом, как и другие блоки, чтобы достичь нод, которые их проверяют.
Другие ноды хранят блоки подтверждения, поскольку они могут рандомно быть выбраны для выдачи отчета о подтверждении. Отчет о подтверждении должен быть выдан в течение определенного количества интервалов с момента создания блока подтверждения (это сетевой параметр). Если нода выбрана в качестве репортера, она должна проверить все входные блоки (и, если применимо, блоки подтверждения, на которые даны ссылки). Если блок в порядке, нода выдает подписанный отчет о подтверждении.
Наличие последних блоков подтверждения является необходимым условием для выпуска отчетов о подтверждении по блокам подтверждения. В отчетах указывается, действительно ли существуют и действительны все входные блоки, на которые ссылается блок подтверждения.
Цель отчетов о подтверждении состоит в том, чтобы продемонстрировать соответствие требуемого размера стейка существованию и действительности набора входных блоков, на которые ссылаются блоки подтверждения. В агрегированном виде пакет отчетов о подтверждении называется сертификатом подтверждения.
На рисунке ниже вы можете видеть случайно выбранную ноду, которая проверяет блок подтверждения, включая все входные блоки, на которые ссылаются, и выдает отчет о подтверждении.
Как только для данного блока подтверждения будет создано достаточное количество отчетов о подтверждении, их можно рассматривать как сертификат подтверждения.
На изображении ниже вы можете видеть случайно выбранную ноду, которая получила достаточное количество отчетов о подтверждении, так что у нее, по сути, есть сертификат подтверждения для блока подтверждения. Это также означает, что нода может включить блок подтверждения в блок ранжирования.
С точки зрения масштабируемости важно знать, что разные блоки подтверждения могут быть созданы конкурентно разными нодами, и они могут ссылаться на несколько одних и тех же входных блоков.
Наконец, мы переходим к блокам ранжирования, которые являются основой для сетевого консенсуса. Случайно выбранная нода возьмет последние блоки подтверждения (которые еще не использовались в предыдущих блоках ранжирования) и, если у нее также есть сертификаты подтверждения для них, вставит их в новый блок ранжирования.
Может случиться так, что нода будет иметь блоки подтверждения, а сертификата подтверждения еще не будет, потому что было выпущено недостаточно отчетов о подтверждении. В этом случае блок подтверждения не попадет в текущий блок ранжирования, который создает нода. Это не имеет значения, потому что этот блок подтверждения, скорее всего, попадет в следующий блок ранжирования (который будет создан другой нодой).
На изображении ниже вы можете видеть ноду, которая создает новый блок ранжирования. У ноды доступно 3 блока подтверждения, но только 2 сертификата подтверждения. Таким образом, блок ранжирования не ссылается на EB 3.
Как мы уже объясняли, блоки подтверждения могут ссылаться друг на друга. Когда набор блоков подтверждения включен в блок ранжирования, только последний блок подтверждения в цепочке должен быть включен в сертификат подтверждения. Причина проста. Сертификат подтверждения для блока подтверждения, который ссылается на предыдущие блоки подтверждения, косвенно охватывает эти предыдущие блоки подтверждения.
Новый блок ранжирования должен ссылаться на предыдущий блок ранжирования. Блок ранжирования считается действительным, если он ссылается на предыдущий действительный блок ранжирования и содержит ссылки на блоки подтверждения с соответствующими действительными сертификатами подтверждения. Блок ранжирования может ссылаться на ноль или более блоков подтверждения.
Нода может не иметь всех доступных блоков подтверждения и блоков входа, на которые они ссылаются, и все же быть в состоянии немедленно принять новое состояние леджера. Построение состояния леджера (загрузка всех блоков) может немного отставать от принятия состояния.
На изображении ниже вы можете увидеть взаимосвязи между всеми типами блоков. Черными стрелками указаны ссылки между IBs и EBs, а также между RBs и EBs. Красные стрелки указывают ссылки IBs на текущее состояние леджера, т.е. на RBs. Синие стрелки указывают на линейность блокчейна, т.е. взаимосвязь между RB, когда новый RB должен следовать за предыдущим RB. По прошествии времени все транзакции будут заноситься в леджер через IBs. На изображении вы также можете видеть синие прямоугольники позади EBs, которые представляют сертификаты подтверждения.
Разделение процесса обработки транзакций от создания блоков
Основная цель функции индоссантов входа - отделить обработку транзакций от создания блоков.
В первом поколении алгоритма нода выполняла и то, и другое, то есть обрабатывала действительные транзакции из своего собственного мемпула и вставляла их в новый блок-кандидат. По сути, это последовательный процесс, в котором только одна нода участвует в каждом раунде (за один период времени). Последующая проверка блока-кандидата другими нодами происходит параллельно.
На изображении ниже вы можете видеть создание новых блоков, содержащих все транзакции из локального мемпула.
Можно ли распараллелить подготовку нового блока (блока ранжирования)?
Алгоритм индоссантов входа позволит подготовить большее количество транзакций на этапе обработки транзакции, поскольку в этом может одновременно участвовать больше нод в сети. Индоссанты проверяют и предварительно одобряют транзакции, что помогает снизить вычислительную нагрузку и требования к пропускной способности для производителей блоков ранжирования, а также увеличить количество и доступность пулов транзакций. Они также позволяют быстрее подтверждать транзакции, которые еще не были включены в цепочку, предоставляя доказательство подтверждения, которое может быть проверено кем угодно.
Блоки ранжирования используются для обеспечения традиционной линейности блокчейна и достижения консенсуса в сети, но вместо того, чтобы содержать транзакции, они содержат ссылки на блоки подтверждения. Блоки входа и подтверждения позволяют выполнять параллельную и конкурентную обработку транзакций.
На рисунке ниже вы можете увидеть распределение работы различных типов блоков с точки зрения сетевого консенсуса. Обратите внимание, что, хотя частота создания блоков в разделе производства блоков такая же, как на предыдущем рисунке, в разделе обработки транзакций происходит больше активности.
Консенсус по-прежнему заключается в выборе наилучшей цепочки блоков, которая соответствует правилам протокола Ouroboros. Индоссанты входа на самом деле подтверждают только те транзакции, которые являются действительными и соответствуют состоянию леджера. Производители блоков ранжирования берут эти одобренные транзакции и включают их в блоки, которые они создают. Консенсус достигается в отношении большего числа транзакций, поскольку они уже были предварительно одобрены, а блоки ранжирования содержат только ссылку на набор блоков подтверждения, которые совместимы друг с другом.
Обратите внимание, что индоссанты входа (IE ноды) не несут ответственности за упорядочивание транзакций в линейную последовательность блоков, а только за их проверку и одобрение. Подтвержденные транзакции затем распространяются по сети в блоках подтверждения с использованием протокола общения нод между собой (gossip).
Улучшения масштабируемости
Самое важное, что следует отметить, - это то, что входные блоки могут создаваться (передаваться потоком) практически постоянно (каждые 0,2-2 секунды). Это означает, что вместо создания одного блока с данными каждые 20 секунд за одно и то же время можно создать от 10 до 100 входных блоков. Высокая частота создания входных блоков не препятствует сетевому консенсусу.
С точки зрения пропускной способности данных масштабируемость может быть улучшена примерно в 10-100 раз, если входные блоки будут иметь тот же размер, что и текущие блоки Cardano. В течение 20 секунд Cardano может обработать от 3000 до 30 000 транзакций. TPS (транзакции в секунду) может составлять от 150 до 1500, если рассматривать только простые (небольшие) транзакции.
Увеличение количества входных блоков оказало бы прямое влияние на повышение масштабируемости. Однако увеличение размера входных блоков может существенно замедлить их распространение в сети. Важно как можно лучше сбалансировать размер входных блоков и частоту их создания. Это относительно приятная проблема, поскольку она в значительной степени отделена от консенсуса, то есть от блоков ранжирования. По мере расширения возможностей Интернета масштабируемость Cardano также может возрасти.
Финализация транзакций также улучшится, поскольку отчеты о подтверждении в основном представляют собой согласие значительной части стейка с содержанием блоков подтверждения (которые ссылаются на блоки входа). Хотя блок ранжирования может стать сиротским (быть потерян), существует относительно высокая вероятность того, что как только транзакция будет вставлена во входной блок, на который будут ссылаться блоки подтверждения, транзакция попадет в блокчейн.
Вывод
Предполагалось, что в статье будет объяснена основная концепция индоссантов входа, и здесь не было места для некоторых крайностей и критических моментов дизайна. Мы вернемся к этому в следующий раз.
// От переводчика: для получения дополнительных переведенных на русский язык статей о Cardano посетите русскоязычный раздел на форуме Cardano. Видеоролики о Cardano на русском языке можно найти на YouTube канале нашего замечательного амбасадора Тимура Сахабутдинова, а также на канале Чарльз Хоскинсон на русском. Хотите поговорить или задать вопрос о Cardano? Тогда приглашаем в наше уютное русскоязычное сообщество Cardano в Telegram. Оставайтесь на связи, все только начинается!