MMS

Джошуа Линд

TL;DR: Блокчейн Aptos использует широкий спектр новых методов для обеспечения высокой пропускной способности, низкой задержки и проверенной синхронизации состояния в децентрализованной сети. Одноранговые узлы могут проверять и синхронизировать более 10 000 транзакций в секунду (TPS) с задержкой менее секунды в Aptos сегодня, и мы уже на пути к 100 000+ TPS.

Обзор

Синхронизация состояний (или синхронизация состояний) — важный, но часто упускаемый из виду аспект дизайна блокчейна. В этом блоге мы обсуждаем эволюцию синхронизации состояний в Aptos и представляем несколько ключевых идей, лежащих в основе дизайна новейшего протокола синхронизации состояний. Далее мы исследуем, как мы недавно увеличили пропускную способность синхронизации состояния в 10 раз, уменьшили задержку в 3 раза и продолжаем прокладывать путь к более быстрой и эффективной синхронизации блокчейна.

Что такое государственная синхронизация?

Сегодня большинство блокчейнов имеют иерархическую структуру с набором активных валидаторов в основе сети. Валидаторы расширяют блокчейн, выполняя транзакции, создавая блоки и достигая консенсуса. Остальные одноранговые узлы в сети (например, полные узлы и клиенты) копируют данные блокчейна, созданные валидаторами (например, блоки и транзакции). Синхронизация состояния — это протокол, который позволяет одноранговым узлам, не являющимся валидаторами, распространять, проверять и сохранять эти данные блокчейна и обеспечивает синхронизацию всех одноранговых узлов в экосистеме. На схеме ниже показано, как это выглядит в Aptos.

Экосистема Aptos (обзор)

Почему синхронизация состояний имеет значение?

Синхронизация состояния редко упоминается при оценке блокчейнов: часто это сноска в официальном документе, посвященном более интересным темам*. Однако синхронизация состояния имеет серьезные последствия для производительности блокчейна, безопасности и взаимодействия с пользователем. Рассмотрим следующее:

  1. Время до завершения и взаимодействие с пользователем: когда новые транзакции выполняются валидаторами, синхронизация состояния отвечает за распространение данных среди одноранговых узлов и клиентов. Если синхронизация состояния медленная или ненадежная, одноранговые узлы будут воспринимать длительные задержки обработки транзакций, искусственно завышая время до завершения. Это оказывает огромное влияние на пользовательский опыт, например, децентрализованные приложения (dApps), децентрализованные биржи (DEX) и обработка платежей будут работать намного медленнее.
  2. Отношения с консенсусом: Валидаторы, которые выходят из строя или отстают от остальной части набора валидаторов, полагаются на синхронизацию состояния, чтобы вернуть их к скорости (т.е. синхронизировать последнее состояние блокчейна). Если синхронизация состояния не может обрабатывать транзакции так же быстро, как они выполняются на основе консенсуса, аварийные валидаторы никогда не смогут восстановиться. Более того, новые валидаторы никогда не смогут начать участвовать в консенсусе (поскольку они никогда не догонят!), а полные узлы никогда не смогут синхронизироваться с последним состоянием (они будут продолжать отставать!).
  3. Последствия для децентрализации : Наличие быстрого, эффективного и масштабируемого протокола синхронизации состояния позволяет: (i) ускорить ротацию активного набора валидаторов, поскольку валидаторы могут более свободно входить и выходить из консенсуса; (ii) больше потенциальных валидаторов на выбор в сети; (iii) больше полных узлов для быстрого подключения к сети без необходимости длительного ожидания; и (iv) более низкие потребности в ресурсах, увеличение неоднородности. Все эти факторы повышают децентрализацию в сети и помогают масштабировать блокчейн по размеру и географии.
  4. Правильность данных . Синхронизация состояния отвечает за проверку правильности всех данных блокчейна во время синхронизации. Это предотвращает изменение, цензуру или фальсификацию данных транзакций злоумышленниками и злоумышленниками в сети и представление их как действительных. Если синхронизация состояния не может этого сделать (или делает это неправильно), полные узлы и клиенты могут быть обмануты, заставляя принимать неверные данные, и это будет иметь разрушительные последствия для сети.

Рассуждения о синхронизации состояния

Чтобы лучше рассуждать о синхронизации состояний, мы сначала вводим общую модель для выполнения блокчейна. Хотя эта модель нацелена конкретно на блокчейн Aptos, ее можно обобщить и на другие.

Мы моделируем блокчейн Aptos как простую базу данных с версиями, где для каждой версии V существует уникальное состояние блокчейна Sⱽ , содержащее все учетные записи и ресурсы в сети. Транзакция T может быть выполнена виртуальной машиной Aptos (VM) в состоянии Sⱽ для создания дельты состояния Dᵀᵥ, представляющей все изменения состояния, которые произошли бы в Sⱽ , если T будет зафиксирован. Когда Dᵀᵥ применяется к Sⱽ (то есть мы считаем T зафиксированным), это приводит к новой версии V+1 и новому состоянию блокчейна Sⱽ⁺¹. Мы называем самое первое состояние блокчейна состоянием генезиса S⁰ . На приведенных ниже диаграммах показано выполнение транзакций и дельта-приложение состояния.

Выполнение транзакции и приложение State Delta (модель)

Каковы цели?

Имея общую модель, мы теперь можем определить несколько основных целей для синхронизации состояний**:

  1. Высокая пропускная способность : синхронизация состояния должна максимизировать количество транзакций, которые могут быть синхронизированы каждым одноранговым узлом в секунду. То есть максимизировать скорость переходов состояний из Sⱽ в Sⱽ⁺¹ для каждого T , зафиксированного валидаторами. Если пропускная способность низкая, это увеличивает время синхронизации и становится узким местом для сети.
  2. Низкая задержка : синхронизация состояния должна минимизировать время, необходимое обновленным одноранговым узлам для синхронизации новых транзакций, совершенных валидаторами. То есть свести к минимуму время, которое требуется пирам в Sⱽ для синхронизации с Sⱽ⁺¹ для каждого T , который был недавно зафиксирован валидаторами. Это влияет на общее время до завершения, воспринимаемое клиентами.
  3. Быстрое время начальной загрузки : синхронизация состояния должна минимизировать время, необходимое новым (или отказавшим) одноранговым узлам для синхронизации с последним состоянием блокчейна. То есть свести к минимуму время, необходимое для синхронизации с Sⱽ (где V — самая высокая версия базы данных, согласованная валидаторами) независимо от текущей версии P партнера и состояния Sᴾ . Это позволяет одноранговым узлам быстрее выполнять полезную работу (например, отвечать на запросы баланса или проверять транзакции).
  4. Устойчивость к сбоям и злоумышленникам. Синхронизация состояния должна быть устойчива к сбоям (например, сбоям компьютера и сети) и допускать злоумышленников в сети, включая других одноранговых узлов. Это означает преодоление широкого спектра атак, например, сфабрикованных данных транзакций, измененных или воспроизведенных сетевых сообщений и атак eclipse .
  5. Устойчивость к ограничениям ресурсов и разнородности: синхронизация состояний должна допускать ограничения ресурсов (например, ЦП, памяти и хранилища) и охватывать разнородность. Учитывая природу децентрализованных сетей, одноранговые узлы будут иметь доступ к разным типам оборудования и оптимизировать их для разных целей. Синхронизация состояния должна учитывать это.

Необходимые строительные блоки

Далее мы представляем набор фундаментальных строительных блоков, необходимых для создания протокола синхронизации состояния. Для краткости мы приводим краткую информацию о каждом строительном блоке ниже и откладываем технические детали до будущей работы (каждый из них сам по себе может стать записью в блоге!):

  1. Постоянное хранилище: для сохранения данных при сбоях и сбоях компьютера (и для возможности распространения данных среди других одноранговых узлов!) мы требуем, чтобы каждый одноранговый узел имел доступ к надежному постоянному хранилищу. В настоящее время мы в Aptos используем RocksDB , но активно изучаем другие варианты.
  2. Поддающиеся проверке данные блокчейна: чтобы предотвратить изменение данных блокчейна злоумышленниками, мы требуем, чтобы данные были аутентифицированы и поддавались проверке. В частности, нам нужно иметь возможность доказать: (i) каждую транзакцию T , которая была выполнена и подтверждена валидаторами; (ii) порядок каждой транзакции T , выполненной и зафиксированной валидаторами; и (iii) результирующее состояние блокчейна Sⱽ после совершения каждой транзакции T . В Aptos мы достигаем этого за счет: (i) построения деревьев меркле над совершенными транзакциями и результирующими состояниями блокчейна; и (ii) привлечение валидаторов для подписи корней merkle этих деревьев для их аутентификации.
  3. Корень доверия: учитывая, что Aptos поддерживает динамические наборы валидаторов (т. е. изменения валидаторов в каждую эпоху), одноранговые узлы должны иметь возможность идентифицировать текущий набор валидаторов из проверенной истории блокчейна Aptos. Мы достигаем этого с помощью: (i) генезисного большого двоичного объекта , аутентифицированного Aptos, который идентифицирует первый набор валидаторов и начальное состояние блокчейна S⁰ ; и (ii) недавняя доверенная путевая точка (например, хэш текущего набора валидаторов и состояние блокчейна Sⱽ ). Вместе генезисный двоичный объект и путевая точка образуют корень доверия, позволяющий одноранговым узлам синхронизировать реальный блокчейн Aptos и предотвращать атаки (например, атаки дальнего действия ).

Достижение 1k TPS: наивный подход

Используя модель и строительные блоки, представленные выше, мы можем теперь проиллюстрировать наивный протокол синхронизации состояния. Этот протокол является упрощением исходного протокола, используемого Aptos (т . е state sync v1. ).

Протокол работает следующим образом: (i) Alice(синхронизирующий одноранговый узел) идентифицирует самую высокую локальную сохраненную версию блокчейна V и состояние Sⱽ . Если такового не существует, Aliceиспользуется генезис, т . е . S⁰ ; (ii) Aliceзатем случайным образом выбирает однорангового узла Bobи запрашивает любые новые последовательные транзакции, совершенные валидаторами; (iii) если Aliceполучит ответ от BobAliceпроверит новые транзакции ( от T⁰ до Tᴺ ) и выполнит их для создания дельты состояния ( от D⁰ᵥ до Dᵀᵥ ₊ₙ); (4)Aliceзатем применит новую дельту состояния к хранилищу вместе с новыми транзакциями, обновив локальное состояние блокчейна с Sⱽ до Sⱽ⁺¹⁺ᴺ . Aliceповторяет этот цикл бесконечно. Псевдокод для протокола выглядит следующим образом:

State Sync v1 (псевдокод)

Мы внедрили этот протокол в Aptos, протестировали его на devnet и проанализировали. Вот некоторые из ключевых наблюдений, которые мы сделали:

  1. Пропускная способность ограничена сетевой задержкой : этот протокол достигает максимума ~1.2k TPS. Однако пропускная способность сильно зависит от сетевых задержек, поскольку Aliceданные запрашиваются последовательно и приходится ждать ответа от однорангового узла. Учитывая, что мы видим среднее время приема-передачи по сети (RTT) 150msв devnet , это неоптимально.
  2. ЦП доминирует над выполнением : когда Aliceполучает новый набор транзакций для синхронизации, мы видим, что 55%время ЦП тратится на выполнение транзакций и 40%тратится на проверку данных, применение дельт состояния к хранилищу и сохранение новых транзакций. Другой 5%связан с обработкой сообщений, сериализацией и другими задачами.
  3. Высокая задержка: при работе сети с максимальной нагрузкой средняя задержка для Aliceполучения новых транзакций возникает ~900 msпосле их фиксации. В первую очередь это связано со Aliceслучайным выбором пиров при запросе данных и без учета топологии сети: пиры, находящиеся ближе к валидаторам, быстрее получат новые транзакции.
  4. Начальная загрузка выполняется медленно : приведенный выше протокол требует Aliceвоспроизведения и синхронизации всех транзакций с момента их создания. Если Aliceсильно отстает от последнего состояния, она должна ждать долгое время, прежде чем сможет сделать что-нибудь полезное (это может занять часы или даже дни!).
  5. Производительностью легко манипулировать : на производительность этого протокола сильно влияют злоумышленники. Как указано в пункте 1 выше, намеренно медленные (или не отвечающие) одноранговые узлы будут Aliceвынуждены проводить длительные периоды времени в ожидании данных и ничего не делать. Таким образом, значительно увеличивается время синхронизации.
  6. Высокое использование ресурсов : этот протокол дорог для всех типов ресурсов: (i) высокая загрузка ЦП, поскольку Aliceнеобходимо повторно выполнять все транзакции; (ii) объем хранилища высок, поскольку он Aliceдолжен хранить все транзакции и состояния блокчейна с момента создания; и (iii) использование сети является высоким, поскольку Aliceвсе транзакции с момента их создания должны приниматься через сеть. Это автоматически налагает высокие затраты и требования к ресурсам, уменьшая неоднородность.
  7. Ресурсы тратятся впустую : пока Aliceидет синхронизация новых данных, пиры в сети тоже синхронизируются от нее. По мере роста числа одноранговых узлов, запрашивающих данные Alice, возникает дополнительная нагрузка чтения на хранилище и ЦП, необходимые для обработки этих запросов. Однако большая часть вычислений, Aliceвыполняемых для обработки этих запросов, расточительна, поскольку одноранговые узлы часто запрашивают одни и те же данные.

Достижение 10 000 транзакций в секунду: оптимизированный подход

Глядя на наивный протокол выше, мы можем внести ряд изменений, чтобы устранить ограничения. Во-первых, мы расширяем протокол для поддержки 2 дополнительных режимов синхронизации:

  1. Синхронизация дельты состояний . Учитывая, что валидаторы уже выполняют транзакции и подтверждают результирующие состояния блокчейна с помощью доказательств Меркла, одноранговые узлы могут полагаться на дельты состояний, созданные валидаторами, чтобы пропустить выполнение транзакции. Это позволяет избежать: (i) высокой стоимости выполнения, сокращая время процессора примерно на 0,5% 55%; и (ii) потребность в виртуальной машине Aptos, что значительно упрощает реализацию дельта-синхронизации. В результате одноранговые узлы теперь могут синхронизироваться, загружая каждую транзакцию T и дельту состояния Dᵀᵥ и применяя их в хранилище для создания нового состояния Sⱽ⁺¹ . Мы отмечаем, что это происходит за счет увеличения использования сети (приблизительно 2.5x).
  2. Синхронизация моментальных снимков блокчейна. Учитывая, что валидаторы подтверждают каждое состояние блокчейна Sⱽ , мы можем дополнительно сократить время начальной загрузки, позволив одноранговым узлам загружать последнее состояние блокчейна напрямую (вместо того, чтобы создавать его с помощью транзакций или дельт состояния). Это значительно сокращает время начальной загрузки и представляет собой аналог моментальной синхронизации в Ethereum. Компромисс заключается в том, что одноранговые узлы не будут хранить какие-либо транзакции или состояния блокчейна до Sⱽ .

Затем мы реализуем ряд общих оптимизаций и дополнительных функций, которые помогут повысить производительность и масштабируемость:

  1. Предварительная выборка данных . Чтобы задержки в сети не влияли на пропускную способность, мы можем выполнять предварительную выборку данных. Одноранговые узлы могут предварительно получать данные транзакций (например, транзакции и дельты состояний) от других одноранговых узлов перед их обработкой, амортизируя сетевые задержки.
  2. Конвейерное выполнение и хранение . Чтобы еще больше увеличить пропускную способность синхронизации, мы можем отделить выполнение транзакций от сохраняемости в хранилище и использовать конвейерную обработку: обычно используемую оптимизацию при проектировании процессоров . Это позволяет выполнять транзакцию  , в то время как транзакция  и дельта состояния Dᵀ¹ᵥ одновременно сохраняются в хранилище.
  3. Одноранговый мониторинг и репутация. Чтобы улучшить наблюдаемость и лучше противостоять злонамеренным одноранговым узлам, мы можем внедрить службу однорангового мониторинга, чтобы: (i) отслеживать одноранговые узлы на предмет злонамеренного поведения (например, передачи неверных данных); (ii) идентифицировать метаданные о каждом узле, такие как сводка всех данных о транзакциях, которые есть у узла, и их воспринимаемое расстояние от набора валидаторов; и (iii) поддерживать локальный балл для каждого однорангового узла. Затем эту информацию можно использовать для оптимизации выбора пиров при запросе новых данных блокчейна.
  4. Кэширование данных . Чтобы уменьшить нагрузку чтения на хранилище и предотвратить синхронизацию состояния с выполнением избыточных вычислений по мере того, как синхронизируется все больше и больше одноранговых узлов, мы можем реализовать кеш данных, который хранит часто запрашиваемые элементы данных и ответы в памяти.
  5. Отсечение хранилища: чтобы предотвратить постоянное увеличение объема хранилища с течением времени (например, по мере совершения большего количества транзакций), мы также можем реализовать динамические сокращения для удаления ненужных данных транзакций и блокчейна из хранилища, например, всего, что старше нескольких дней, недель или месяцев. в зависимости от конфигурации пира.

Мы внедрили эти модификации и создали новый протокол синхронизации состояния (т . е state sync v2. ). Мы протестировали его на devnet и заметили:

  1. Пропускная способность увеличилась в 5x-10x : при выполнении транзакций (без параллельного выполнения ) протокол теперь достигает максимума ~4.5k TPS, в основном за счет конвейерной обработки и предварительной выборки данных (т. е. протокол теперь способен полностью насыщать ЦП). При синхронизации дельт состояния протокол достигает значительно более 10K TPS, что является еще одним результатом предотвращения выполнения транзакций. В обоих случаях задержка сети больше не влияет на пропускную способность.
  2. Задержка была уменьшена в 3 раза : при работе сети с максимальной нагрузкой мы теперь видим, что средняя задержка для Aliceполучения новых транзакций возникает ~300 msпосле их фиксации. Это связано с предварительной выборкой данных и более эффективным выбором пиров: с пирами, которые более отзывчивы и ближе к валидаторам, связываются чаще.
  3. Начальная загрузка значительно быстрее : одноранговые узлы, использующие синхронизацию моментальных снимков блокчейна, могут загружаться намного быстрее. Более того, на время начальной загрузки больше не влияет длина блокчейна (то есть количество транзакций), а скорее количество сетевых ресурсов для синхронизации. В настоящее время в devnet одноранговые узлы могут выполнить начальную загрузку в течение нескольких минут***.
  4. Снижаются требования к ресурсам . Благодаря нескольким режимам синхронизации и сокращению объема хранилища требования к ресурсам были снижены. Кроме того, теперь поддерживается неоднородность, поскольку одноранговые узлы могут гибко выбирать стратегию синхронизации. Например: (i) одноранговые узлы с ограниченным ЦП могут пропускать выполнение транзакции; (ii) одноранговые узлы с ограниченным хранилищем могут настроить секатор на агрессивный режим; и (iii) одноранговые узлы, которые хотят быстро обновляться, могут выполнять синхронизацию моментальных снимков блокчейна.
  5. Ресурсы используются более эффективно : при обработке запросов на синхронизацию от одноранговых узлов мы видим значительно сниженную нагрузку чтения на хранилище и меньшую трату ЦП. Это связано с новым кэшем данных, который хранит часто запрашиваемые элементы данных и ответы в памяти. Мы также видим, что по мере роста числа синхронизирующих одноранговых узлов в devnet кэш данных становится более эффективным, например, с 20синхронизирующими одноранговыми узлами мы видим коэффициент попаданий в кеш 70%-80%на запрос. Но с 60одноранговыми узлами мы видим процент попаданий в кеш 93%-98%. Это происходит за счет дополнительной ~150 MBоперативной памяти для обслуживания кеша.

100k TPS и выше?

Хотя мы уже улучшили пропускную способность в 10 раз и задержку в 3 раза, мы понимаем, что еще многое предстоит сделать. Особенно, если мы хотим соответствовать Block-STM и сделать Aptos уровнем 1 для всех !

Итак, как мы собираемся туда добраться? Что ж, мы уже приступили к нашей следующей цели синхронизации состояния: 100 000+ TPS! Хотя мы планируем сохранить подробности для будущего поста в блоге, мы хотели дать некоторые подсказки очень внимательному читателю:

  1. Пакетная обработка транзакций . В настоящее время Aptos рассматривает каждую транзакцию как поддающуюся проверке, т. е. доказательства Меркла, используемые для аутентификации и проверки данных, работают с точностью до транзакций. Это делает проверку и хранение невероятно дорогими. Один из способов избежать этого — выполнять пакетную обработку транзакций, т. е. проверять пакеты (или блоки!) транзакций.
  2. Сжатие сети: пропускная способность сети часто становится узким местом в одноранговых сетях, и Aptos не является исключением. В настоящее время предварительная выборка синхронизации состояния может выполнять выборку ~45K TPSв devnet до насыщения полосы пропускания. Это проблема, если мы хотим масштабироваться. К счастью, мы уже поняли, что одноранговые узлы распространяют данные, используя неэффективный формат сериализации, и с помощью стандартного сжатия мы можем уменьшить объем передаваемых данных более чем на 10x.
  3. Более быстрая запись в хранилище: в настоящее время пропускная способность синхронизации состояния ограничена временем, которое требуется для сохранения данных блокчейна в хранилище. Мы активно изучаем различные оптимизации и улучшения, которые мы можем сделать, чтобы устранить это узкое место, в том числе: (i) более эффективные структуры данных; (ii) более оптимальные конфигурации хранения; и (iii) альтернативные механизмы хранения.
  4. Параллельная обработка данных . До сих пор нам требовалось, чтобы синхронизация состояний обрабатывала данные последовательно (например, обрабатывала транзакции в последовательно возрастающих версиях). Однако существует ряд существующих подходов, которые позволили бы нам избежать этого требования и использовать параллельную обработку данных для значительного увеличения пропускной способности, например, сегментирование блокчейна!

До скорого!

Если вы, как и мы, увлечены разработкой алгоритмов, их применением на практике и реальным влиянием на будущее Web3, свяжитесь с нами — мы нанимаем в Aptos.

*Как и консенсус 🙂
**Мы неявно предполагаем, что синхронизация состояний должна синхронизировать состояния всех сетевых ресурсов . Стратегии частичной синхронизации (например, легкие клиенты, ориентированные на определенные учетные записи) выходят за рамки и будут обсуждаться в будущем.
*** К этому показателю следует относиться с долей скептицизма. Сеть разработчиков Aptos стирается раз в две недели, поэтому синхронизация ограничена. Для более продолжительных сетей потребуется дополнительная оценка (например, наши поощрительные тестовые сети ).

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *