Хорошо известно, что Ethereum, самая популярная dApps платформа, обрабатывает меньше чем 20 транзакций в секунду. Из-за этого ограничения цена транзакций и время на их подтверждение очень высоки: несмотря на то, что блок в Ethereum публикуется раз в 10-12 секунд, согласно ETH Gas Station время между отправкой транзакции и тем как она действительно попадает в блок в среднем 1.2 минуты. Низкая пропускная способность, высокие цены и долгое подтверждение транзакций не позволяет запускать на Ethereum какие-либо высокопроизводительные сервисы.
Основная причина того, что Ethereum не может обрабатывать больше 20 транзакций в секунду заключается в том, что каждая нода в Ethereum должна проверить каждую транзакцию. За пять лет с выхода Ethereum было предложено много идей как решить эту проблему. Эти решения можно грубо разбить на две группы: те, которые предлагают делегировать выполнение транзакций небольшой группе нод с очень хорошим железом, и те, которые предлагают каждой ноде обрабатывать только подмножество всех транзакций. Пример первого подхода — это Thunder, в котором блоки создаются только одной нодой, что позволяет, по утверждениям разработчиков, получать 1200 транзакций в секунду, что в 100 раз больше чем у Ethereum. Другие примеры из первой категории — это Algorand, SpaceMesh, Solana. Все эти протоколы улучшают разные аспекты протокола и позволяют выполнять больше транзакций чем в Ethereum, но все ограничены скоростью одной (пусть и очень мощной) машины.
Второй подход, в котором каждая нода обрабатывает только подмножество транзакций, называется Шардинг. Это то как Ethereum Foundation планирует увеличить пропускную способность Ethereum.
В этом посте я расскажу как работает Шардинг в Blockchain на примере нескольких протоколов, которые сейчас находятся в разработке.
Терминология
В самой простой реализации вместо того, чтобы поддерживать один блокчейн, мы будем поддерживать несколько, и назовем каждый такой блокчейн “шард”. Каждый шард поддерживается независимым множеством нод, которые проверяют транзакции и создают блоки. Здесь и далее я буду называть такие ноды валидаторами.
Каждый шард отвечает за какое-то подмножество контрактов и аккаунтов. Предположим пока что что транзакции всегда оперируют только с контрактами и аккаунтами внутри одного шарда. Такого упрощенного дизайна достаточно, чтобы показать некоторые интересные проблемы и особенности шардинга.
Первая проблема с тем, что у каждого шарда свои валидаторы, заключается в том, что если у нас есть 10 шадров, то каждый шард теперь в 10 раз менее надежен, чем был бы один блокчейн. Так, если блокчейн с X валидаторами решит сделать хард-форк в шардированную систему с 10 шардами, и разобьет X валидаторов между 10 шардами, в каждом шарде теперь только X/10 валидаторов, и получение контроля над шардом требует получения контроля над 5.1% (51% / 10) валидаторов.
Что приводит к первому интересному вопросу: а кто назначает валидаторов на шарды? Наличие контроля над 5.1% валидаторов является проблемой только если все 5.1% валидаторов в одном шарде. Если валидаторы не могут сами выбрать какому шарду они назначены, получение контроля над 5.1% валидаторов до того как они назначены на шарды не позволит получить контроль ни над одним шардом.
Почти все существующие предложенные дизайны шардинга используют некоторый источник случайных чисел чтобы назначать валидаторов на шарды. Получение случайных чисел в распределенной системе в которой участники друг другу не доверяют — это само по себе не до конца решенная проблема сегодня, которую мы в этой статье не затронем, и просто допустим, что такой источник случайных чисел у нас есть.
И получение случайных чисел, и назначение валидаторов — это вычисления в масштабах всей системы, не специфичные ни какому конкретному шарду. Для таких вычислений в современных дизайнах шардированных блокчейнов существует дополнительный выделенный блокчейн, который существует исключительно чтобы выполнять вычисления в масштабах системы. Помимо случайных чисел и назначения валидаторов такими вычислениями могут быть получения хешей последних блоков с шардов и их сохранение; обработка залогов в Proof-of-Stake системах, и изучение доказательств неправильного поведения с сопутствующим отбиранием таких залогов; перебалансировка шардов, если такая функция предусмотрена. Такой блокчейн называется Beacon chain в Ethereum 2.0 и Near Protocol, Relay chain в PolkaDot, и Cosmos Hub в Cosmos.
В этом посте мы будем называть такой блокчейн “центральным блокчейном”. Существования центрального блокчейна приводит нас к следующей интересной теме — квадратичному шардированию.
Шардинг часто презентуют как решение, которое бесконечно масштабируется с увеличением количества нод. Вероятно, можно действительно создать систему с таким свойством, но системы с центральным блокчейном имеют ограничение сверху на количество шард, и как следствие не имеют бесконечной масштабируемости. Легко понять почему: центральный блокчейн выполняет некоторые вычисления, такие как назначение валидаторов и сохранение последних состояний шард, сложность которых пропорциональна количеству шард. Так как сам центральный блокчейн не шардирован, и его пропускная способность ограничена пропускной способностью каждой ноды, количество шард, которые он может поддерживать, ограничено.
Давайте посмотрим как изменится пропускная способность всей системы, если мощность нод, его поддерживающих, вырастет в k раз. Каждый шард сможет обрабатывать в k раз больше транзакций, а центральный блокчейн сможет поддерживать в k раз больше шард. Таким образом пропускная способность всей системы вырастет в k^2 раз. Отсюда название “квадратичное шардирование” (quadratic sharding).
Сложно предсказать сколько шард сегодня сможет поддерживать центральный блокчейн, но вероятнее всего в ближайшее будущее мы не приблизимся к лимиту транзакций для шардированного блокчейна с квадратичным шардированием. Скорее всего мы раньше упремся в лимит того, сколько надо нод, чтобы поддерживать такое количество шард.