Мерклизация SVM на SOON

Продвинутый1/27/2025, 12:53:10 AM
SOON Network вводит структуру дерева Меркля виртуальной машины Solana (SVM), чтобы решить проблему отсутствия корней глобального состояния. Это усовершенствование укрепляет возможности SVM в проверке целостности, доказательствах мошенничества и межслойных операциях в системе агрегации. Путем встраивания корня состояния непосредственно в блокчейн SVM SOON повышает безопасность и масштабируемость, обеспечивая более надежную поддержку для агрегации SVM.

Виртуальная машина Solana (SVM) все более широко принимается в качестве слоя исполнения для различных решений уровня 2 (L2). Однако ключевым ограничением в оригинальном дизайне SVM является неясность его глобального корня состояния. Это создает значительные препятствия для систем rollup, где глобальные корни состояния критичны для обеспечения целостности, обеспечения доказательств мошенничества и поддержки операций между слоями.

В rollup предлагающий отправляет корень состояния L2 (корень Меркла) на уровень-1 (L1) периодически, устанавливая контрольные точки для цепи L2. Эти контрольные точки позволяют доказательства включения для любого состояния учетной записи, обеспечивая бессостоятельное выполнение от одной контрольной точки к другой. Доказательства мошенничества полагаются на этот механизм, поскольку участники могут предоставить доказательства включения для проверки действительных входных данных во время споров. Кроме того, деревья Меркла улучшают безопасность канонических мостов, позволяя пользователям генерировать доказательства включения для транзакций вывода, обеспечивая бесдоверительные взаимодействия между L2 и L1.

Для решения этих проблем, Сеть SOONвнедряет деревья Merkle в исполнительный слой SVM, что позволяет клиентам предоставлять доказательства включения. SOON интегрируется с Proof-of-History, используя уникальные записи для встраивания корней состояний непосредственно в блокчейны на основе SVM. Благодаря этому инновационному решению стек SOON может поддерживать новые роллапы на основе SVM с улучшенной безопасностью, масштабируемостью и утилитарностью.

Проблема Merklization Solana

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

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

Давайте посмотрим, как происходит мерклизация на других цепях, а затем выявим вызовы, представленные архитектурой протокола Solana.

Деревья Меркля на Биткоине

На Bitcoin транзакции хранятся в блоке с использованием Дерево Меркля, корень которого хранится в заголовок блокаПротокол Bitcoin будет хешировать входы и выходы транзакции (а также некоторые другие метаданные) вИдентификатор транзакции(TxID). Для подтверждения состояния на Bitcoin пользователь может просто рассчитать доказательство Меркля для проверки TxID по отношению к корню Меркля блока.

Этот процесс верификации также подтверждает состояние, поскольку Tx ID уникален для определенного набора входов и выходов, которые отражают изменения состояния адреса. Обратите внимание, что транзакции Bitcoin также могут содержать Скрипты Taproot, которые производят выходные транзакции, которые могут быть проверены во время верификации, часто путем повторного запуска скрипта с использованием входных данных транзакции и учета данных свидетелей скрипта, и проверки по ее выходам.

Деревья Меркля на Ethereum

Подобно Bitcoin, Ethereum хранит транзакции с использованием специальной структуры данных (полученной из дерева Меркля) под названием Меркл Патрисия Трие (MPT). Эта структура данных разработана для быстрых обновлений и оптимизации больших наборов данных. Естественно, это связано с тем, что у Ethereum значительно больше входов и выходов для управления, чем у Bitcoin.

Виртуальная машина Ethereum(EVM) действует как глобальная машина состояний. EVM в основном является гигантской распределенной вычислительной средой, которая поддерживает исполняемыеумные контракты, каждый из которых резервирует свое собственное адресное пространство в глобальной памяти. В результате клиенты, которые хотят проверить состояние на Ethereum, должны учитывать не только результат транзакции (логи, возвращаемый код и т. д.), но и изменения глобального состояния в результате транзакции.

К счастью, EVM умело использует три важных структуры трие, корни которых хранятся в каждом заголовке блока.

  • Дерево состояний: Гигантское хранилище ключ-значение всех состояний на Ethereum, включая каждый адрес Ethereum и данные, хранящиеся в каждом счете. Для смарт-контрактов эти счета хранят еще одно дерево, называемое трай.Хранилище трие, что является еще одной картой ключ-значение всех данных смарт-контракта для его адресного пространства.
  • Transactions trie: Хранилище ключ-значение всех транзакций в блоке, где ключом является идентификатор транзакции, а значением - данные транзакции.
  • Дерево квитанций: Trie, содержащий квитанции (статус, события) от каждой транзакции в блоке, хешированные индексом каждой транзакции в блоке. Каждая квитанция содержит информацию о выполнении транзакции, в том числе хэш транзакции после состояния.

Учитывая транзакцию, клиент может доказать ее включение в блок, оценивая корень дерева транзакций (как Bitcoin), ее результат, оценивая дерево квитанций, и изменения глобального состояния, оценивая дерево состояния.

Деревья Меркла на Solana

Одной из причин высокой пропускной способности Соланы является то, что у нее нет многодеревной структуры, как у Эфириума. Лидеры Соланы вычисляют деревья Меркля при создании блоков, но их структура отличается от тех, что в EVM. К сожалению, в этом и заключается проблема для роллапов, основанных на SVM.

Solana мерклизует транзакции в так называемые записи, и в одном слоте может быть несколько записей; следовательно, несколько корней транзакций на блок. Более того, Solana вычисляет корень Меркла состояния учета только один раз за эпоху (приблизительно 2,5 дня), и этот корень недоступен в учетной книге.

Фактически, заголовки блоков Solana вообще не содержат никаких Merkle-корней. Вместо этого они содержат предыдущий и текущий хэш блока, которая вычисляется через Solana’s Доказательство историиАлгоритм (PoH). PoH требует, чтобы валидаторы непрерывно регистрировали «тики», рекурсивно хешируя записи блоков, которые могут быть пустыми или содержать пакеты транзакций. Финальный тик (хеш) алгоритма PoH является хешем этого блока.

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

Однако существует еще один хэш, который могут использовать клиенты: банковский хэш. Иногда называемый хэшем слота, банковские хэши доступны в СлотХеши sysvarсчет, который может быть запрошен клиентом. Хэш банка создается для каждого блока (слота) из нескольких входов:

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

Как видно, банковский хэш перегружен несколькими входными хэшами, что усложняет задачу клиентов, пытающихся доказать информацию о транзакциях или состоянии. Кроме того, только банковский хэш для банка, выполнившего «хэш эпохи счетов» - хэш всех счетов один раз за эпоху - будет включать в себя этот конкретный корень. Кроме того, учетная запись SlotHashes sysvar усекается до последних 512 банковских хэшей.

Решение Merklization SOON

Сеть SOONэто SVM L2 поверх Ethereum. Интегрируя мерклизацию в SOON, мы отдали предпочтение использованию проверенных и хорошо зарекомендовавших себя решений ради стабильности, а не изобретая велосипед. При принятии решения, какие структуры данных или хэширующие алгоритмы использовать, мы учитывали их совместимость с L1 контрактамиСтек оптимизма, их способность интегрироваться бесшовно в архитектуру Solana и то, смогут ли они достичь высокой производительности в рамках учетной модели Solana.

Мы обнаружили, что по мере увеличения числа учетных записей модель хранения Меркл Патриция Три (MPT) основана на LSM-деревопроизводил бы большую амплификацию чтения/записи на диске, что привело бы к потере производительности. В конечном итоге, мы решили интегрировать Erigon MPTна основе отличной работы по Rust, выполненной rETHкоманда и добавление поддержки модели учетной записи Solana.

Архитектура

Как упоминалось ранее, дерево состояний SOON - это MPT, построенное для поддержки учетных записей Solana. Таким образом, мы определили тип учетной записи, совместимый с SVM, чтобы служить данными каждого листового узла.

struct TrieSolanaAccount {

lamports: u64,

data: Vec,

исполнимый: bool,

rent_epoch: u64,

владелец: Pubkey,

}

Для того чтобы модуль MPT мог подписываться на последнее состояние учетных записей SVM в реальном времени, мы ввели уведомитель об учетной записи. Во время Банковского Этапа уведомитель об учетной записи информирует модуль MPT об изменениях в состоянии учетной записи, и MPT поэтапно обновляет эти изменения в структуре трие.

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

outputRoot = keccak256(version, state_root, withdraw_root, l2_block_hash)

MPT-модуль SOON одновременно поддерживает два типа структур trie: State Trie для глобального состояния и Withdraw Trie для транзакций вывода. Предлагающий периодически генерирует outputRoot по состоянию root и withdraw root и отправляет его на L1.

В настоящее время SOON вычисляет корневое состояние и корневое изъятие один раз каждые 450 слотов и добавляет его в блокчейн L2. В результате обеспечивается согласованность данных MPT среди других узлов в сети. Однако структура блока Solana не включает заголовок блока, что означает отсутствие места для хранения корневого состояния. Давайте внимательно рассмотрим основную структуру блокчейна Solana, а затем изучим, как SOON вводит уникальную запись для хранения корневого состояния.

Блокчейн Solana состоит из слотов, которые генерируются модулем PoH. Слот содержит несколько записей, каждая запись включает такты и транзакции. На уровнях сети и хранения слот хранится и передается с использованием измельчатькак самая маленькая единица. Фрагменты могут быть преобразованы в записи и обратно.

[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq, Clone)]

pub struct Entry {

/// Количество хэшей с момента предыдущего идентификатора записи.

pub num_hashes: u64,

/// Хэш SHA-256 num_hashesпосле предыдущего идентификатора записи.

pub hash: Hash,

/// Неупорядоченный список транзакций, которые были замечены до идентификатора записи

/// сгенерированы. Они могли быть замечены до предыдущего идентификатора записи, но были

отодвинут обратно в этот список, чтобы обеспечить детерминированную интерпретацию реестра.

общественные транзакции: Vec,

}

Мы следовали структуре блокчейна, сгенерированной PoH, и сохранили структуру shred, что позволило нам повторно использовать существующий уровень хранения, сетевой уровень и каркас RPC Solana. Чтобы сохранить дополнительные данные на L2 блокчейне, мы ввели уникальную запись. Этот атрибут позволяет нам настраивать полезную нагрузку записи и определять независимые правила валидации для данных.

pub const UNIQUE_ENTRY_NUM_HASHES_FLAG: u64 = 0x8000_0000_0000_0000;

/// Уникальная запись - это особый тип записи. Который полезен, когда нам нужно сохранить какие-то данные в

/// blockstore but do not want to verify it.

///

/// The layout of num_hashes есть:

/// |…1 бит…|…63 бита…|

/// \ _ _/

/// \ \

/// флаг пользовательское поле

pub trait UniqueEntry: Sized {

fn encode_to_entries(&self) -> Vec;

fn decode_from_entries(

   записи: impl IntoIterator<Элемент = Запись>,

) -> Result;

}

pub fn unique_entry(custom_field: u64, hash: Hash) -> Entry {

Вход {

   num_hashes: num_hashes(custom_field),   хэш,   транзакции: vec![],

}

}

pub fn num_hashes(custom_field: u64) -> u64 {

assert!(custom_field < (1 << 63));

UNIQUE_ENTRY_NUM_HASHES_FLAG | custom_field

}

pub fn is_unique(entry: &Entry) -> bool {

entry.num_hashes & UNIQUE_ENTRY_NUM_HASHES_FLAG != 0

}

В UniqueEntry num_hashes используется в качестве макета битов, где первый бит флага используется для различения между Entry и Unique Entry, а следующие 63 бита используются для определения типа полезной нагрузки. Поле хеша служит в качестве полезной нагрузки, содержащей необходимые пользовательские данные.

Давайте рассмотрим пример использования трех уникальных записей для сохранения хэша слота, корня состояния и корня вывода.

/// Уникальная запись корневого MPT.

[derive(Default, Debug, Clone, PartialEq, Eq)]

pub struct MptRoot {

pub слот: Слот,

pub state_root: B256,

pub withdrawal_root: B256,

}

impl UniqueEntry для MptRoot {

fn encode_to_entries(&self) -> Vec {

   пусть slot_entry = unique_entry(0, slot_to_hash(self.slot));   пусть state_root_entry = unique_entry(1, self.state_root.0.into());   let withdrawal_root_entry = unique_entry(2, self.withdrawal_root.0.into());   ВЭК! [slot_entry, state_root_entry, withdrawal_root_entry]

}

fn decode_from_entries(
entries: impl IntoIterator,
) -> Результат {

   let mut entries = entries.into_iter();   let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?;   let slot = hash_to_slot(entry.hash);   let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?;   let state_root = B256::from(entry.hash.to_bytes());   let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?;   let withdrawal_root = B256::from(entry.hash.to_bytes();   Ok(MptRoot {       slot,       state_root,       withdrawal_root,   })

}
}

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

Выводы и мосты на местном языке

Родной мост - это ключевой элемент инфраструктуры для решений уровня 2, ответственный за передачу сообщений между L1 и L2. Сообщения от L1 к L2 называются транзакциями депозита, в то время как сообщения от L2 к L1 называются транзакциями вывода.

Депозитные транзакции обычно обрабатываются производная трубопроводи требуют только одной транзакции от пользователя на уровне L1. Однако транзакции вывода более сложны и требуют от пользователя отправки трех транзакций для завершения процесса:

  1. Сначала пользователь должен отправить начальную транзакцию вывода на уровне L2.
  2. Как только outputRoot, содержащий эту первоначальную транзакцию вывода, отправляется предложившим на уровень L1, пользователю необходимо отправить доказательство включения для транзакции вывода на уровень L1. После успешной проверки начинается период вызова.
  3. После окончания периода оспаривания пользователь отправляет окончательную транзакцию для завершения всего процесса вывода.

Включение доказательства транзакции вывода гарантирует, что вывод произошел на уровне L2, что значительно повышает безопасность канонического моста.

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

В отличие от EVM, данные контракта SVM хранятся в поле данных учетных записей, и все типы учетных записей существуют на одном и том же уровне иерархии.

SOON представил программу моста Bridge1111111111111111111111111111111111111. Каждый раз, когда пользователь инициирует транзакцию вывода, программа моста генерирует глобально уникальный индекс для каждой транзакции вывода и использует этот индекс в качестве базы для создания новой Программный производный счет(PDA) для сохранения соответствующей транзакции вывода.

[derive(Clone, Copy, Debug, PartialEq)]

pub struct WithdrawalTransaction {

/// счетчик вывода

pub nonce: U256,

/// пользователь, который хочет вывести

отправитель: Публичный ключ,

/// адрес пользователя в L1

pub target: Адрес,

/// снять сумму в лампортах

pub значение: U256,

/// лимит газа в L1

pub gas_limit: U256,

/// вывод calldata в L1

pub данные: L1WithdrawalCalldata,

}

Мы определили структуру WithdrawalTransaction для хранения транзакций вывода в поле данных PDA.

Этот дизайн работает аналогично стеку OP. После того как outputRoot, содержащий транзакцию вывода, отправлен на уровень L1, пользователь может представить доказательство включения для транзакции вывода на уровень L1, чтобы начать период вызова.

Доказательства неисправности

После того как предлагающий отправляет outputRoot на L1, это означает, что состояние L2 было урегулировано. Если оппонент обнаружит, что предлагающий отправил неправильное состояние, они могут инициировать вызов для защиты средств на мосту.

Один из самых важных аспектов построения надежной схемы - обеспечить переход блокчейна из состояния S1 в состояние S2 в бессостоятельном режиме. Это гарантирует, что контракт арбитража на уровне L1 может воспроизвести инструкции программы без состояния для выполнения арбитража.

Однако в начале этого процесса оппонент должен доказать, что все начальные входы в состоянии S1 действительны. К ним относятся состояния участвующих счетов (например, лампорты, данные, владелец и т. д.). В отличие от EVM, SVM естественным образом разделяет состояние счета от вычислений. API SVM Anza позволяет передавать учетные записи в SVM с помощью типажа TransactionProcessingCallback, как показано ниже.

pub trait TransactionProcessingCallback {

fn account_matches_owners(&self, account: &Pubkey, owners: &[Pubkey]) -> Option;

fn get_account_shared_data(&self, pubkey: &Pubkey) -> Option;

fn add_builtin_account(&self, _name: &str, _program_id: &Pubkey) {}

}

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

Заключение

SOON отмечает важный этап в развитии экосистемы SVM. Интегрируя мерклизацию, SOON решает проблему отсутствия глобального корня состояния в Solana, обеспечивая важные функции, такие как доказательства включения для доказательств неисправности, безопасные выводы и бессостоятельное выполнение.

Кроме того, дизайн мерклизации SOON в рамках SVM может позволить легким клиентам на цепочках, основанных на SVM, даже если сама Solana в настоящее время не поддерживает легких клиентов. Даже возможно, что некоторые элементы дизайна смогут помочь внедрению легких клиентов на главной цепочке также.

Используя деревья Меркля-Патриши (MPT) для управления состоянием, SOON выравнивается с инфраструктурой Ethereum, улучшая взаимодействие и продвигая решения L2 на основе SVM. Это инновация укрепляет экосистему SVM, улучшая безопасность, масштабируемость и совместимость, способствуя развитию децентрализованных приложений.

Disclaimer:

  1. Эта статья перепечатана из [Средний]. Все авторские права принадлежат оригинальному автору [@0xandrewz и @realbuffalojoe]. Если есть возражения по этому повторному изданию, пожалуйста, свяжитесь с Gate Learnкоманда, и они быстро справятся с этим.
  2. Ответственность за отказ: Взгляды и мнения, выраженные в этой статье, являются исключительно мнениями автора и не являются инвестиционными советами.
  3. Команда Gate Learn перевела статью на другие языки. Копирование, распространение или плагиатство переведенных статей запрещено, если не указано иное.

Мерклизация SVM на SOON

Продвинутый1/27/2025, 12:53:10 AM
SOON Network вводит структуру дерева Меркля виртуальной машины Solana (SVM), чтобы решить проблему отсутствия корней глобального состояния. Это усовершенствование укрепляет возможности SVM в проверке целостности, доказательствах мошенничества и межслойных операциях в системе агрегации. Путем встраивания корня состояния непосредственно в блокчейн SVM SOON повышает безопасность и масштабируемость, обеспечивая более надежную поддержку для агрегации SVM.

Виртуальная машина Solana (SVM) все более широко принимается в качестве слоя исполнения для различных решений уровня 2 (L2). Однако ключевым ограничением в оригинальном дизайне SVM является неясность его глобального корня состояния. Это создает значительные препятствия для систем rollup, где глобальные корни состояния критичны для обеспечения целостности, обеспечения доказательств мошенничества и поддержки операций между слоями.

В rollup предлагающий отправляет корень состояния L2 (корень Меркла) на уровень-1 (L1) периодически, устанавливая контрольные точки для цепи L2. Эти контрольные точки позволяют доказательства включения для любого состояния учетной записи, обеспечивая бессостоятельное выполнение от одной контрольной точки к другой. Доказательства мошенничества полагаются на этот механизм, поскольку участники могут предоставить доказательства включения для проверки действительных входных данных во время споров. Кроме того, деревья Меркла улучшают безопасность канонических мостов, позволяя пользователям генерировать доказательства включения для транзакций вывода, обеспечивая бесдоверительные взаимодействия между L2 и L1.

Для решения этих проблем, Сеть SOONвнедряет деревья Merkle в исполнительный слой SVM, что позволяет клиентам предоставлять доказательства включения. SOON интегрируется с Proof-of-History, используя уникальные записи для встраивания корней состояний непосредственно в блокчейны на основе SVM. Благодаря этому инновационному решению стек SOON может поддерживать новые роллапы на основе SVM с улучшенной безопасностью, масштабируемостью и утилитарностью.

Проблема Merklization Solana

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

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

Давайте посмотрим, как происходит мерклизация на других цепях, а затем выявим вызовы, представленные архитектурой протокола Solana.

Деревья Меркля на Биткоине

На Bitcoin транзакции хранятся в блоке с использованием Дерево Меркля, корень которого хранится в заголовок блокаПротокол Bitcoin будет хешировать входы и выходы транзакции (а также некоторые другие метаданные) вИдентификатор транзакции(TxID). Для подтверждения состояния на Bitcoin пользователь может просто рассчитать доказательство Меркля для проверки TxID по отношению к корню Меркля блока.

Этот процесс верификации также подтверждает состояние, поскольку Tx ID уникален для определенного набора входов и выходов, которые отражают изменения состояния адреса. Обратите внимание, что транзакции Bitcoin также могут содержать Скрипты Taproot, которые производят выходные транзакции, которые могут быть проверены во время верификации, часто путем повторного запуска скрипта с использованием входных данных транзакции и учета данных свидетелей скрипта, и проверки по ее выходам.

Деревья Меркля на Ethereum

Подобно Bitcoin, Ethereum хранит транзакции с использованием специальной структуры данных (полученной из дерева Меркля) под названием Меркл Патрисия Трие (MPT). Эта структура данных разработана для быстрых обновлений и оптимизации больших наборов данных. Естественно, это связано с тем, что у Ethereum значительно больше входов и выходов для управления, чем у Bitcoin.

Виртуальная машина Ethereum(EVM) действует как глобальная машина состояний. EVM в основном является гигантской распределенной вычислительной средой, которая поддерживает исполняемыеумные контракты, каждый из которых резервирует свое собственное адресное пространство в глобальной памяти. В результате клиенты, которые хотят проверить состояние на Ethereum, должны учитывать не только результат транзакции (логи, возвращаемый код и т. д.), но и изменения глобального состояния в результате транзакции.

К счастью, EVM умело использует три важных структуры трие, корни которых хранятся в каждом заголовке блока.

  • Дерево состояний: Гигантское хранилище ключ-значение всех состояний на Ethereum, включая каждый адрес Ethereum и данные, хранящиеся в каждом счете. Для смарт-контрактов эти счета хранят еще одно дерево, называемое трай.Хранилище трие, что является еще одной картой ключ-значение всех данных смарт-контракта для его адресного пространства.
  • Transactions trie: Хранилище ключ-значение всех транзакций в блоке, где ключом является идентификатор транзакции, а значением - данные транзакции.
  • Дерево квитанций: Trie, содержащий квитанции (статус, события) от каждой транзакции в блоке, хешированные индексом каждой транзакции в блоке. Каждая квитанция содержит информацию о выполнении транзакции, в том числе хэш транзакции после состояния.

Учитывая транзакцию, клиент может доказать ее включение в блок, оценивая корень дерева транзакций (как Bitcoin), ее результат, оценивая дерево квитанций, и изменения глобального состояния, оценивая дерево состояния.

Деревья Меркла на Solana

Одной из причин высокой пропускной способности Соланы является то, что у нее нет многодеревной структуры, как у Эфириума. Лидеры Соланы вычисляют деревья Меркля при создании блоков, но их структура отличается от тех, что в EVM. К сожалению, в этом и заключается проблема для роллапов, основанных на SVM.

Solana мерклизует транзакции в так называемые записи, и в одном слоте может быть несколько записей; следовательно, несколько корней транзакций на блок. Более того, Solana вычисляет корень Меркла состояния учета только один раз за эпоху (приблизительно 2,5 дня), и этот корень недоступен в учетной книге.

Фактически, заголовки блоков Solana вообще не содержат никаких Merkle-корней. Вместо этого они содержат предыдущий и текущий хэш блока, которая вычисляется через Solana’s Доказательство историиАлгоритм (PoH). PoH требует, чтобы валидаторы непрерывно регистрировали «тики», рекурсивно хешируя записи блоков, которые могут быть пустыми или содержать пакеты транзакций. Финальный тик (хеш) алгоритма PoH является хешем этого блока.

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

Однако существует еще один хэш, который могут использовать клиенты: банковский хэш. Иногда называемый хэшем слота, банковские хэши доступны в СлотХеши sysvarсчет, который может быть запрошен клиентом. Хэш банка создается для каждого блока (слота) из нескольких входов:

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

Как видно, банковский хэш перегружен несколькими входными хэшами, что усложняет задачу клиентов, пытающихся доказать информацию о транзакциях или состоянии. Кроме того, только банковский хэш для банка, выполнившего «хэш эпохи счетов» - хэш всех счетов один раз за эпоху - будет включать в себя этот конкретный корень. Кроме того, учетная запись SlotHashes sysvar усекается до последних 512 банковских хэшей.

Решение Merklization SOON

Сеть SOONэто SVM L2 поверх Ethereum. Интегрируя мерклизацию в SOON, мы отдали предпочтение использованию проверенных и хорошо зарекомендовавших себя решений ради стабильности, а не изобретая велосипед. При принятии решения, какие структуры данных или хэширующие алгоритмы использовать, мы учитывали их совместимость с L1 контрактамиСтек оптимизма, их способность интегрироваться бесшовно в архитектуру Solana и то, смогут ли они достичь высокой производительности в рамках учетной модели Solana.

Мы обнаружили, что по мере увеличения числа учетных записей модель хранения Меркл Патриция Три (MPT) основана на LSM-деревопроизводил бы большую амплификацию чтения/записи на диске, что привело бы к потере производительности. В конечном итоге, мы решили интегрировать Erigon MPTна основе отличной работы по Rust, выполненной rETHкоманда и добавление поддержки модели учетной записи Solana.

Архитектура

Как упоминалось ранее, дерево состояний SOON - это MPT, построенное для поддержки учетных записей Solana. Таким образом, мы определили тип учетной записи, совместимый с SVM, чтобы служить данными каждого листового узла.

struct TrieSolanaAccount {

lamports: u64,

data: Vec,

исполнимый: bool,

rent_epoch: u64,

владелец: Pubkey,

}

Для того чтобы модуль MPT мог подписываться на последнее состояние учетных записей SVM в реальном времени, мы ввели уведомитель об учетной записи. Во время Банковского Этапа уведомитель об учетной записи информирует модуль MPT об изменениях в состоянии учетной записи, и MPT поэтапно обновляет эти изменения в структуре трие.

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

outputRoot = keccak256(version, state_root, withdraw_root, l2_block_hash)

MPT-модуль SOON одновременно поддерживает два типа структур trie: State Trie для глобального состояния и Withdraw Trie для транзакций вывода. Предлагающий периодически генерирует outputRoot по состоянию root и withdraw root и отправляет его на L1.

В настоящее время SOON вычисляет корневое состояние и корневое изъятие один раз каждые 450 слотов и добавляет его в блокчейн L2. В результате обеспечивается согласованность данных MPT среди других узлов в сети. Однако структура блока Solana не включает заголовок блока, что означает отсутствие места для хранения корневого состояния. Давайте внимательно рассмотрим основную структуру блокчейна Solana, а затем изучим, как SOON вводит уникальную запись для хранения корневого состояния.

Блокчейн Solana состоит из слотов, которые генерируются модулем PoH. Слот содержит несколько записей, каждая запись включает такты и транзакции. На уровнях сети и хранения слот хранится и передается с использованием измельчатькак самая маленькая единица. Фрагменты могут быть преобразованы в записи и обратно.

[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq, Clone)]

pub struct Entry {

/// Количество хэшей с момента предыдущего идентификатора записи.

pub num_hashes: u64,

/// Хэш SHA-256 num_hashesпосле предыдущего идентификатора записи.

pub hash: Hash,

/// Неупорядоченный список транзакций, которые были замечены до идентификатора записи

/// сгенерированы. Они могли быть замечены до предыдущего идентификатора записи, но были

отодвинут обратно в этот список, чтобы обеспечить детерминированную интерпретацию реестра.

общественные транзакции: Vec,

}

Мы следовали структуре блокчейна, сгенерированной PoH, и сохранили структуру shred, что позволило нам повторно использовать существующий уровень хранения, сетевой уровень и каркас RPC Solana. Чтобы сохранить дополнительные данные на L2 блокчейне, мы ввели уникальную запись. Этот атрибут позволяет нам настраивать полезную нагрузку записи и определять независимые правила валидации для данных.

pub const UNIQUE_ENTRY_NUM_HASHES_FLAG: u64 = 0x8000_0000_0000_0000;

/// Уникальная запись - это особый тип записи. Который полезен, когда нам нужно сохранить какие-то данные в

/// blockstore but do not want to verify it.

///

/// The layout of num_hashes есть:

/// |…1 бит…|…63 бита…|

/// \ _ _/

/// \ \

/// флаг пользовательское поле

pub trait UniqueEntry: Sized {

fn encode_to_entries(&self) -> Vec;

fn decode_from_entries(

   записи: impl IntoIterator<Элемент = Запись>,

) -> Result;

}

pub fn unique_entry(custom_field: u64, hash: Hash) -> Entry {

Вход {

   num_hashes: num_hashes(custom_field),   хэш,   транзакции: vec![],

}

}

pub fn num_hashes(custom_field: u64) -> u64 {

assert!(custom_field < (1 << 63));

UNIQUE_ENTRY_NUM_HASHES_FLAG | custom_field

}

pub fn is_unique(entry: &Entry) -> bool {

entry.num_hashes & UNIQUE_ENTRY_NUM_HASHES_FLAG != 0

}

В UniqueEntry num_hashes используется в качестве макета битов, где первый бит флага используется для различения между Entry и Unique Entry, а следующие 63 бита используются для определения типа полезной нагрузки. Поле хеша служит в качестве полезной нагрузки, содержащей необходимые пользовательские данные.

Давайте рассмотрим пример использования трех уникальных записей для сохранения хэша слота, корня состояния и корня вывода.

/// Уникальная запись корневого MPT.

[derive(Default, Debug, Clone, PartialEq, Eq)]

pub struct MptRoot {

pub слот: Слот,

pub state_root: B256,

pub withdrawal_root: B256,

}

impl UniqueEntry для MptRoot {

fn encode_to_entries(&self) -> Vec {

   пусть slot_entry = unique_entry(0, slot_to_hash(self.slot));   пусть state_root_entry = unique_entry(1, self.state_root.0.into());   let withdrawal_root_entry = unique_entry(2, self.withdrawal_root.0.into());   ВЭК! [slot_entry, state_root_entry, withdrawal_root_entry]

}

fn decode_from_entries(
entries: impl IntoIterator,
) -> Результат {

   let mut entries = entries.into_iter();   let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?;   let slot = hash_to_slot(entry.hash);   let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?;   let state_root = B256::from(entry.hash.to_bytes());   let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?;   let withdrawal_root = B256::from(entry.hash.to_bytes();   Ok(MptRoot {       slot,       state_root,       withdrawal_root,   })

}
}

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

Выводы и мосты на местном языке

Родной мост - это ключевой элемент инфраструктуры для решений уровня 2, ответственный за передачу сообщений между L1 и L2. Сообщения от L1 к L2 называются транзакциями депозита, в то время как сообщения от L2 к L1 называются транзакциями вывода.

Депозитные транзакции обычно обрабатываются производная трубопроводи требуют только одной транзакции от пользователя на уровне L1. Однако транзакции вывода более сложны и требуют от пользователя отправки трех транзакций для завершения процесса:

  1. Сначала пользователь должен отправить начальную транзакцию вывода на уровне L2.
  2. Как только outputRoot, содержащий эту первоначальную транзакцию вывода, отправляется предложившим на уровень L1, пользователю необходимо отправить доказательство включения для транзакции вывода на уровень L1. После успешной проверки начинается период вызова.
  3. После окончания периода оспаривания пользователь отправляет окончательную транзакцию для завершения всего процесса вывода.

Включение доказательства транзакции вывода гарантирует, что вывод произошел на уровне L2, что значительно повышает безопасность канонического моста.

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

В отличие от EVM, данные контракта SVM хранятся в поле данных учетных записей, и все типы учетных записей существуют на одном и том же уровне иерархии.

SOON представил программу моста Bridge1111111111111111111111111111111111111. Каждый раз, когда пользователь инициирует транзакцию вывода, программа моста генерирует глобально уникальный индекс для каждой транзакции вывода и использует этот индекс в качестве базы для создания новой Программный производный счет(PDA) для сохранения соответствующей транзакции вывода.

[derive(Clone, Copy, Debug, PartialEq)]

pub struct WithdrawalTransaction {

/// счетчик вывода

pub nonce: U256,

/// пользователь, который хочет вывести

отправитель: Публичный ключ,

/// адрес пользователя в L1

pub target: Адрес,

/// снять сумму в лампортах

pub значение: U256,

/// лимит газа в L1

pub gas_limit: U256,

/// вывод calldata в L1

pub данные: L1WithdrawalCalldata,

}

Мы определили структуру WithdrawalTransaction для хранения транзакций вывода в поле данных PDA.

Этот дизайн работает аналогично стеку OP. После того как outputRoot, содержащий транзакцию вывода, отправлен на уровень L1, пользователь может представить доказательство включения для транзакции вывода на уровень L1, чтобы начать период вызова.

Доказательства неисправности

После того как предлагающий отправляет outputRoot на L1, это означает, что состояние L2 было урегулировано. Если оппонент обнаружит, что предлагающий отправил неправильное состояние, они могут инициировать вызов для защиты средств на мосту.

Один из самых важных аспектов построения надежной схемы - обеспечить переход блокчейна из состояния S1 в состояние S2 в бессостоятельном режиме. Это гарантирует, что контракт арбитража на уровне L1 может воспроизвести инструкции программы без состояния для выполнения арбитража.

Однако в начале этого процесса оппонент должен доказать, что все начальные входы в состоянии S1 действительны. К ним относятся состояния участвующих счетов (например, лампорты, данные, владелец и т. д.). В отличие от EVM, SVM естественным образом разделяет состояние счета от вычислений. API SVM Anza позволяет передавать учетные записи в SVM с помощью типажа TransactionProcessingCallback, как показано ниже.

pub trait TransactionProcessingCallback {

fn account_matches_owners(&self, account: &Pubkey, owners: &[Pubkey]) -> Option;

fn get_account_shared_data(&self, pubkey: &Pubkey) -> Option;

fn add_builtin_account(&self, _name: &str, _program_id: &Pubkey) {}

}

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

Заключение

SOON отмечает важный этап в развитии экосистемы SVM. Интегрируя мерклизацию, SOON решает проблему отсутствия глобального корня состояния в Solana, обеспечивая важные функции, такие как доказательства включения для доказательств неисправности, безопасные выводы и бессостоятельное выполнение.

Кроме того, дизайн мерклизации SOON в рамках SVM может позволить легким клиентам на цепочках, основанных на SVM, даже если сама Solana в настоящее время не поддерживает легких клиентов. Даже возможно, что некоторые элементы дизайна смогут помочь внедрению легких клиентов на главной цепочке также.

Используя деревья Меркля-Патриши (MPT) для управления состоянием, SOON выравнивается с инфраструктурой Ethereum, улучшая взаимодействие и продвигая решения L2 на основе SVM. Это инновация укрепляет экосистему SVM, улучшая безопасность, масштабируемость и совместимость, способствуя развитию децентрализованных приложений.

Disclaimer:

  1. Эта статья перепечатана из [Средний]. Все авторские права принадлежат оригинальному автору [@0xandrewz и @realbuffalojoe]. Если есть возражения по этому повторному изданию, пожалуйста, свяжитесь с Gate Learnкоманда, и они быстро справятся с этим.
  2. Ответственность за отказ: Взгляды и мнения, выраженные в этой статье, являются исключительно мнениями автора и не являются инвестиционными советами.
  3. Команда Gate Learn перевела статью на другие языки. Копирование, распространение или плагиатство переведенных статей запрещено, если не указано иное.
即刻开始交易
注册并交易即可获得
$100
和价值
$5500
理财体验金奖励!