НОВОЕ: Helius приобретает Light Protocol
Обновление Solana v1.18
Блог/Обновления

Всё, что нужно знать об обновлении Solana v1.18

Developer Experience Engineer0xIchigo в X0xIchigo в LinkedIn0xIchigo на GitHub
Чтение: 19 мин

Большое спасибо Rex St. John и Mike MacCana за рецензирование этой статьи.

Введение

Принятие обновления Solana 1.18 сверхбольшинством — важная веха. Оно содержит множество улучшений и новых функций, повышающих производительность, надежность и эффективность сети. Одно из самых заметных изменений — появление центрального планировщика. Новый планировщик призван упростить обработку транзакций и обеспечить более точный и эффективный расчет приоритета. Другие улучшения среды выполнения и развертывания программ помогают поддерживать стабильную производительность даже при пиковой нагрузке на сеть.

В этой статье рассматриваются изменения и улучшения релиза 1.18. Мы разберем причины этих изменений, особенности новых функций и их ожидаемое влияние на работу сети. Независимо от того, управляете ли вы валидатором, разрабатываете приложения или просто пользуетесь Solana, этот подробный обзор обновления 1.18 даст вам информацию, необходимую для понимания и использования преимуществ новых улучшений.

Сначала необходимо рассказать об Anza — недавно созданной компании-разработчике, которая стоит за этими изменениями, — и о ее роли в дальнейшем развитии Solana.

Что такое Anza?

Anza — недавно созданная компания по разработке ПО, основанная бывшими руководителями и ведущими инженерами Solana Labs. Ее создание стало стратегическим шагом по укреплению экосистемы Solana, направленным на повышение надежности, децентрализации и устойчивости сети. Anza была основана для развития экосистемы Solana: создания критически важной инфраструктуры, участия в разработке ключевых протоколов и поддержки инноваций в области новых инструментов.

В команду основателей входят Jeff Washington, Stephen Akridge, Jed Halfon, Amber Christiansen, Pankaj Garg, Jon Cinque и несколько ведущих инженеров Solana Labs.

Anza сосредоточена на разработке и совершенствовании клиентов валидаторов Solana посредством создания Agave — форка клиента валидатора Solana Labs. Амбиции Anza не ограничиваются разработкой собственного клиента валидатора: компания стремится улучшать всю экосистему. В частности, она разрабатывает Token Extensions и специализированный набор инструментов Rust / Clang. Поддерживая открытый и совместный подход к разработке, Anza стремится ускорить развитие и совершенствование экосистемы Solana.

Что такое Agave?

Как кратко упоминалось в предыдущем разделе, Agave — это форк клиента валидатора Solana Labs, разработку которого возглавляет Anza. В данном контексте термин «форк» означает, что команда разработчиков Anza взяла существующий код из репозитория Solana Labs и начала отдельную от исходной кодовой базы ветвь разработки. Это позволяет Anza внедрять собственные улучшения, функции и оптимизации в клиент Solana Labs.

Процесс миграции

Перенос клиента в организацию Anza на GitHub начался 1 марта. Сначала Agave будет зеркально повторять репозиторий Solana Labs, чтобы сообщество успело адаптироваться. В этот период Anza закроет запросы на включение изменений (PR) и перенесет актуальные задачи в репозиторий Agave. Версии 1.17 и 1.18 Agave и клиента Solana Labs будут функционально идентичны. Anza планирует выпустить Agave v2.0 этим летом, после чего клиент Solana Labs будет архивирован, а всей сети порекомендуют перейти на новый клиент Agave.

За процессом миграции с Solana Labs на Agave можно следить в общедоступном разделе GitHub.

Среда выполнения Agave

Среда выполнения Agave наследует базовую архитектуру Solana Virtual Machine (SVM) и служит основой для выполнения ключевых функций, определенных средой выполнения Sealevel. 

Протокол Solana определяет среду выполнения как критически важный компонент для обработки транзакций и обновления состояния в базе данных аккаунтов. Эта спецификация была принята и дополнительно усовершенствована в клиентах Agave и Firedancer. Главная особенность SVM — способность параллельно выполнять все программы Solana и изменять состояния аккаунтов.

Понятие банка играет ключевую роль в обработке транзакций и понимании изменений версии 1.18. Банк — это одновременно логика и представление состояния реестра в определенный момент времени. Он выступает сложным контроллером, который управляет базой данных аккаунтов, отслеживает клиентские аккаунты, контролирует выполнение программ, а также обеспечивает целостность и последовательное развитие реестра Solana. Банк инкапсулирует состояние, полученное в результате транзакций определенного блока, и служит снимком реестра на данный момент времени.

Каждый банк содержит кеши и ссылки, необходимые для выполнения транзакций, поэтому его можно инициализировать из предыдущего снимка или блока генезиса. На этапе Banking Stage, где валидатор обрабатывает транзакции, банки используются для формирования блоков и последующей проверки их целостности. Этот жизненный цикл включает загрузку аккаунтов, обработку транзакций, заморозку банка для фиксации состояния и, наконец, его укоренение, которое гарантирует постоянство состояния.

В общих чертах механизм обработки транзакций в среде выполнения Agave отвечает за загрузку, компиляцию и выполнение программ. Он использует JIT-компиляцию и кеширует скомпилированные программы, чтобы повысить эффективность выполнения и избежать ненужной повторной компиляции. Перед развертыванием программы компилируются в формат eBPF. Затем среда выполнения использует набор инструментов rBPF для создания виртуальной машины eBPF, которая выполняет JIT-компиляцию из eBPF в инструкции машинного кода x86_64, в полной мере используя доступное оборудование. Это обеспечивает эффективное выполнение программ.

Обновление 1.18 добавляет центральный планировщик транзакций, тесно связанный с повышением операционной эффективности среды выполнения Agave. Улучшая компиляцию, выполнение и управление транзакциями через банки, обновление 1.18 упрощает планирование и делает его эффективнее. В результате транзакции обрабатываются быстрее, а пропускная способность растет. Новая среда выполнения Agave и ее клиент служат основой этих улучшений, поэтому перед подробным разбором нового планировщика важно получить общее представление о них. 

Если вы хотите узнать больше о среде выполнения Agave, рекомендую прочитать статью Joe Caulfield на эту тему. В ней всё подробно разобрано и приведено много полезных фрагментов кода.

Более эффективный планировщик транзакций

Текущая реализация

В конвейере обработки транзакций пакеты транзакций сначала поступают в систему через входящий трафик. Затем на этапе SigVerify проверяются их подписи. Этот этап подтверждает, что каждая транзакция действительна и авторизована отправителем.

После проверки подписей транзакции передаются на этап Banking Stage. Banking Stage включает шесть потоков: два обрабатывают транзакции голосования из Transaction Processing Unit (TPU) или Gossip, а четыре — транзакции, не связанные с голосованием. Потоки независимы друг от друга и получают пакеты из общего канала. То есть SigVerify отправляет пакеты группами, а каждый поток извлекает транзакции из общего канала и сохраняет их в локальном буфере. 

Локальный буфер получает транзакции, определяет их приоритет и сортирует соответствующим образом. Эта очередь динамическая: она постоянно обновляется с учетом изменений статуса транзакций и требований сети в реальном времени. При добавлении транзакций их порядок пересматривается, чтобы первыми обрабатывались транзакции с наивысшим приоритетом.

Этот процесс идет непрерывно, а дальнейшая судьба пакетов транзакций зависит от позиции валидатора в расписании лидеров. Если валидатор не должен стать лидером в ближайшее время, он перенаправляет пакеты следующему лидеру и удаляет их. По мере приближения назначенного лидерского слота (примерно за ~20 слотов) валидатор продолжает пересылать пакеты, но больше не удаляет их. Это позволяет включить пакеты в один из собственных блоков, если другие лидеры их не обработают. За два слота до того, как стать лидером, валидатор начинает удерживать пакеты: принимает их, но ничего с ними не делает, чтобы обработать после получения роли лидера.

При создании блока каждый поток берет первые 128 транзакций из своей локальной очереди, пытается получить блокировки, а затем проверяет, загружает, выполняет, записывает и фиксирует транзакции. Если получить блокировку не удается, попытка обработки транзакции повторяется позже. Рассмотрим каждый этап подробнее:

  • Блокировка: на этом этапе определяется, для каких транзакций поток может получить блокировки. Каждая транзакция читает и записывает некоторое количество аккаунтов, поэтому валидатор должен убедиться в отсутствии конфликтов
  • Проверки: на этом этапе проверяется, не устарела ли транзакция и не была ли она уже обработана. Обратите внимание: банки содержат кеш статусов, который отслеживает транзакции за последние 150–300 слотов
  • Загрузка: на этом этапе загружаются аккаунты, необходимые для выполнения конкретной транзакции. Также проверяется, может ли плательщик комиссии оплатить ее и является ли вызванная программа действительной. По сути, на этом этапе загружаются аккаунты и выполняется начальная настройка
  • Выполнение: на этом этапе выполняется каждая транзакция
  • Запись: результаты выполненных транзакций отправляются в сервис Proof of History для хеширования. На этом этапе отправляется подпись транзакции
  • Фиксация: если этап записи завершается успешно, транзакции фиксируются. На этом этапе изменения также передаются обратно в систему аккаунтов, чтобы последующие транзакции в этом или следующих слотах видели обновленное состояние каждого аккаунта‍
  • Снятие блокировки: блокировки каждого аккаунта, установленные на первом этапе, снимаются

Banking Stage использует подход с несколькими итераторами для создания таких пакетов транзакций. Несколько итераторов — это паттерн программирования, который позволяет одновременно обходить набор данных в нескольких последовательностях. Представьте нескольких читателей одной книги: каждый начинает с отдельной главы, а вместе они координируются, чтобы не читать одну и ту же страницу одновременно, если это может помешать пониманию содержания друг другом. В Banking Stage роль «читателей» выполняют итераторы, а роль «книги» — набор ожидающих обработки транзакций. Цель нескольких итераторов — эффективно отбирать транзакции и группировать их в пакеты, которые можно обработать без конфликтов блокировок.

Сначала транзакции сериализуются в вектор по приоритету. Это дает нескольким итераторам структурированную последовательность, которую можно разделить на неконфликтующие пакеты. Обход начинается с начала сериализованного вектора, а итераторы размещаются в точках, где транзакции не конфликтуют друг с другом. Таким образом создаются пакеты из 128 транзакций без конфликтов чтения-записи или записи-записи. Если транзакция конфликтует с формируемым пакетом, она пропускается и остается непомеченной. Благодаря этому ее можно включить в последующий пакет, где конфликта уже нет. Этот итеративный процесс динамически корректируется по мере обработки транзакций. 

После успешного формирования пакета транзакции выполняются. В случае успеха они записываются в сервис Proof of History и транслируются в сеть.

Проблемы текущей реализации

В текущей реализации есть несколько участков, которые могут отрицательно влиять на производительность, создавать узкие места при обработке транзакций и приводить к непоследовательной приоритизации. Главные причины этих проблем — архитектура Banking Stage и особенности обработки транзакций в системе.

Основная проблема заключается в том, что четыре независимых потока, обрабатывающих транзакции, не связанные с голосованием, по-разному оценивают приоритет транзакций. Это расхождение может вызывать колебания или непоследовательность в порядке транзакций. Проблема становится особенно заметной, когда конфликтуют все высокоприоритетные транзакции. Поскольку каждый поток фактически случайным образом извлекает пакеты из общего канала SigVerify, каждый из них получает случайный набор транзакций. Во время конкурентных событий, например популярного выпуска NFT, множество высокоприоритетных транзакций, скорее всего, окажется сразу в нескольких потоках Banking Stage. Это может привести к конфликтам блокировок между потоками. Потоки с разными представлениями о приоритетах могут конкурировать за обработку высокоприоритетных транзакций, непреднамеренно тратя вычислительное время на неудачные попытки блокировки.

Представьте Banking Stage как оркестр, где каждый поток — отдельная группа инструментов: струнные, медные духовые, деревянные духовые и ударные. В идеале дирижер должен координировать группы, чтобы обеспечить гармоничное исполнение. Однако текущая система напоминает оркестр, который пытается исполнить сложное произведение без дирижера. Каждая группа играет свою мелодию, регулярно вступая в конфликт с другими. Высокоприоритетные транзакции — это сольные партии, которые все группы пытаются играть одновременно, создавая путаницу. Отсутствие координации показывает необходимость в централизованном «дирижере», который обеспечит эффективность и согласованность обработки транзакций Solana, подобно дирижеру оркестра.

Новый планировщик транзакций

Обновление 1.18 добавляет центральный поток планирования, который заменяет прежнюю модель с четырьмя независимыми банковскими потоками, каждый из которых самостоятельно управлял приоритизацией и обработкой транзакций. В новой структуре центральный планировщик — единственный получатель транзакций с этапа SigVerify. Он формирует приоритетную очередь и использует граф зависимостей для управления приоритизацией и обработкой транзакций.

Этот граф зависимостей называется prio-graph. Это ориентированный ациклический граф с ленивым вычислением по мере добавления новых транзакций. Транзакции вставляются в граф, формируя цепочки выполнения, а затем извлекаются в порядке временного приоритета. Среди конфликтующих транзакций более высокий приоритет всегда получает та, которая была вставлена первой. В приведенном выше примере есть транзакции от A до H. Обратите внимание, что транзакции A и E имеют наивысший приоритет в своих цепочках и не конфликтуют. Планировщик движется слева направо и обрабатывает транзакции пакетами:

Транзакции A и E обрабатываются первым пакетом, затем B и F, после этого C, D и G, а последним пакетом — H. Как видно, транзакции с наивысшим приоритетом находятся в верхней части графа, то есть слева. Планировщик просматривает транзакции по убыванию приоритета и выявляет конфликты. Если транзакция конфликтует с более приоритетной, в графе создается ребро, обозначающее эту зависимость: например, C и D конфликтуют с B.

Новая модель планировщика устраняет несколько ключевых проблем, присущих подходу с несколькими итераторами:

  • Последовательная обработка приоритетов: новая система централизует прием и планирование транзакций, поэтому все они обрабатываются в едином порядке приоритета. Это устраняет колебания, которые раньше возникали из-за различного представления потоков о приоритетах транзакций
  • Сокращение задержек обработки: prio-graph формирует пакеты, которые с высокой вероятностью будут успешно выполнены без конфликтов блокировок. Это сокращает время обработки и задержки из-за конкуренции за блокировки. Обратите внимание на формулировку «с высокой вероятностью»: нельзя утверждать, что пакеты prio-graph никогда не сталкиваются с ошибками блокировки, поскольку они могут конфликтовать с потоками голосования, хотя это крайне редкий пограничный случай
  • Масштабируемость и гибкость: новая архитектура планировщика позволяет увеличивать число потоков, не опасаясь роста количества конфликтов блокировок. Это возможно благодаря централизованному представлению блокировок и более контролируемому распределению транзакций между рабочими потоками 

Ожидается, что центральный планировщик в версии 1.18 значительно улучшит обработку транзакций, снизив сложность и накладные расходы прежней системы. Вероятными результатами станут более быстрая обработка транзакций, рост пропускной способности и повышение стабильности сети. Из-за задержек с выпуском версии 1.18 планировщик успели улучшить по сравнению с первоначальным вариантом. Например, предварительная проверка прекомпиляций для транзакций была перенесена в рабочие потоки для повышения эффективности. Кроме того, теперь лимиты CU стали более обоснованными, а соотношение расчетных и фактических значений намного ниже, чем у старого планировщика. Новый планировщик теперь может использовать CU для регулирования очередей запланированных задач, предотвращая избыточное накопление задач из-за конфликтов аккаунтов.

Обратите внимание: центральный планировщик по умолчанию отключен, и при запуске валидатора его необходимо активировать с помощью нового флага --block-production-method central-scheduler. Сейчас он включается только явно, но в будущих релизах станет планировщиком по умолчанию. Старый планировщик можно включить с помощью флага --block-production-method thread-local-multi-iterator. Сейчас он активен по умолчанию, но в будущих релизах не используйте его: центральный планировщик гораздо эффективнее и устраняет проблемы старого.

Более эффективный расчет приоритета 

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

Новый подход корректирует расчет приоритета транзакции, учитывая комиссии и связанные затраты по формуле Приоритет = Комиссии / (Затраты + 1). Здесь комиссии — это комиссии, связанные с конкретной транзакцией, а затраты — потребление вычислительных и других ресурсов, определяемое моделью затрат Solana. Добавление «1» в знаменатель — мера защиты от деления на ноль. 

Формулу можно разобрать подробнее, чтобы точнее определить Комиссии и Затраты:

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

Улучшенное развертывание программ

Версия 1.18 также значительно улучшает развертывание программ с точки зрения надежности развертывания и эффективности выполнения. 

Новое обновление устраняет проблему, из-за которой программы, развернутые в последнем слоте эпохи, некорректно применяли изменения среды выполнения, запланированные для следующей эпохи. Поэтому программа, развернутая в этот переходный период, ошибочно использовала старую среду выполнения. Версия 1.18 корректирует процесс развертывания, чтобы среда выполнения любой программы, развернутой в конце эпохи, соответствовала среде следующей эпохи.

Версия 1.18 также устраняет невозможность задать цену или лимит вычислительных единиц для транзакций развертывания: в команды CLI для развертывания программ добавлен флаг --with-compute-unit-price. Этот флаг можно использовать с командами solana program deploy и solana program write-buffer. Лимит вычислительных единиц устанавливается путем моделирования каждого типа транзакции развертывания и приравнивается к количеству потребленных вычислительных единиц.  

Еще одно важное улучшение касается обработки хешей блоков при развертывании крупных программ. До версии 1.18 пропускная способность транзакций, отправленных с sign_all_messages_and_send, ограничивалась 100 TPS. При развертывании крупных программ количество транзакций может исчисляться тысячами. Из-за этого транзакции могли задерживаться и использовать устаревшие хеши блоков, поскольку многие из них ожидали более 10 секунд. В версии 1.18 подписание транзакций развертывания свежим хешем блока выполняется после задержки регулирования. Теперь хеши блоков обновляются каждые 5 секунд, поэтому развертывания с более чем 500 транзакциями смогут использовать более свежий хеш блока.

Кроме того, версия 1.18 улучшает обработку развертывания программ и проверку транзакций в сети. Раньше некоторые программы ошибочно помечались как FailedVerification из-за ошибок при определении состояния аккаунтов. Из-за этого метку могли получить программы, которые фактически успешно прошли все проверки. Теперь неактивные программы правильно определяются как Closed. Благодаря этому для повторной проверки отмечаются только проблемные программы, а ненужных повторных проверок становится меньше.

Процесс обновления состояний программ также был усовершенствован. Теперь программы могут перейти из состояния Closed в активное состояние в том же слоте, где они были развернуты. Это позволяет программам быстрее и надежнее начинать работу, что особенно важно в периоды высокого спроса. Однако стоит отметить, что это улучшение по-прежнему учитывает задержку в один слот при снятии, повторном и новом развертывании, а также задержку видимости в один слот. Поэтому, хотя эти изменения помогают эффективнее управлять нагрузкой на сеть и предотвращать определенные виды перегрузки, они не оказывают существенного влияния на рабочий процесс разработчиков dApp.

«Исправление перегрузки» — более эффективная борьба с перегрузкой

Версия 1.18.11 для Testnet, представленная как «Исправление перегрузки», предложила изменения для устранения недавней перегрузки Solana. Обратите внимание: этот релиз не относится исключительно к версии 1.18, и его обратно портировали в 1.17.31. Тем не менее его важно рассмотреть.

Главное изменение заключается в том, что теперь QUIC рассматривает узлы с крайне малым стейком как узлы без стейка в рамках взвешенного по стейку качества обслуживания (SWQoS). Это изменение устраняет возможность злоупотребления системой, когда ноды с очень малым стейком получали непропорционально большую пропускную способность. Кроме того, прежние метрики не позволяли определить соотношение отправленных и ограниченных пакетов от нод со стейком и без него. Поэтому были добавлены новые метрики, обеспечивающие лучшую наблюдаемость. Обработка фрагментов пакетов также была оптимизирована: экземпляры vec заменили на smallvec, чтобы избежать одного выделения памяти на пакет. Это возможно, поскольку размер потоков соответствует размеру пакета и ожидается небольшое число потоков. 

Раньше на этапе Banking Stage все пакеты пересылались следующей ноде. Однако версия 1.18 меняет это поведение: теперь пересылаются только пакеты от нод со стейком. В результате соединения со стейком становятся еще важнее, поскольку имеют больший вес при расчете приоритета и пересылке транзакций.

Улучшенная документация

Обновление 1.18 также значительно улучшает поддержку переводов официальной документации Solana, делая ее доступнее для пользователей по всему миру. Среди изменений — обновление CLI и конфигурации Crowdin, упрощающее синхронизацию документов на разных языках, а также новая команда serve для более удобного локального тестирования через Docusaurus. Кроме того, улучшена обработка статического содержимого: PDF-файлы теперь ссылаются непосредственно на объекты blob в GitHub, что позволяет избежать проблем с относительными путями в переведенных сборках.

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

Заключение

Обновление 1.18, разработку которого возглавляет Anza, существенно улучшает обработку транзакций, расчет приоритета, развертывание программ, официальную документацию и общую производительность сети. Благодаря центральному планировщику и различным исправлениям недавней перегрузки Solana лучше подготовлена к пиковым нагрузкам и может обеспечить эффективную и надежную работу сети. Solana — лучший претендент на роль масштабируемого блокчейна, и это обновление подтверждает ее потенциал.

Если вы дочитали до этого места — спасибо, анон! Обязательно укажите ниже свой адрес электронной почты, чтобы не пропускать новости Solana. Хотите узнать больше? Изучите последние статьи в блоге Helius и продолжите свое знакомство с Solana уже сегодня.

Дополнительные ресурсы

Подпишитесь на Helius

Следите за новостями разработки на Solana и получайте уведомления о наших публикациях

Увеличенное изображение