Хабрахабр

TON: Telegram Open Network. Часть 2: Блокчейны, шардирование

TON

В предыдущей части я описал её самый базовый уровень — способ взаимодействия узлов между собой. Данный текст — продолжение серии статей, в которых я рассматриваю структуру (предположительно) готовящейся к выходу в этом году распределенной сети Telegram Open Network (TON).

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

Сегодня посмотрим на основной компонент TON — блокчейн.

Базовые понятия

Некий набор данных, идентифицируемый 256-битным числом account_id (чаще всего это публичный ключ владельца аккаунта). Аккаунт (account). ниже нулевой воркчейн), под этими данными подразумевается баланс пользователя. В базовом случае (см. «Занять» конкретный account_id может кто угодно, но изменять его значение можно только по определённым правилам.

По сути — частный случай аккаунта, дополненный кодом смарт-контракта и хранилищем его переменных. Смарт-контракт (smart-contract). Если в случае «кошелька» можно зачислять и списывать деньги из него по относительно простым и заранее определённым правилам, то в случае смарт-контракта эти правила записаны в виде его кода (на некоем Тьюринг-полном языке программирования).

Совокупность состояний всех аккаунтов/смарт-контрактов (в абстрактном смысле — хэш-таблица, где ключами являются идентификаторы аккаунтов, а значениями — хранимые в аккаунтах данные). Состояние блокчейна (state of blockchain).

Выше я употребил выражение «зачислять и списывать деньги» — это частный пример сообщения («передать N грамм с аккаунта account_1 на аккаунт account_2»). Сообщение (message). Результатом доставки таких сообщений обычному аккаунту является увеличение его баланса, а смарт-контракту — выполнение его кода (который обработает прием сообщения). Очевидно, отправить такое сообщение может только узел, владеющий закрытым ключом аккаунта account_1 — и способный подтвердить это подписью. Разумеется, возможны и другие сообщения (переносящие не денежные суммы, а произвольные данные между смарт-контрактами).

Факт доставки сообщения называется транзакцией. Транзакция (transaction). Именно из транзакций (записей о доставке сообщений) состоят блоки в блокчейне. Транзакции изменяют состояние блокчейна. О конкретике упаковки этих «диффов» (и восстановлении полного состояния по ним) пойдёт речь в следующей статье. В этом плане можно представлять себе состояние блокчейна как инкрементальную базу данных — все блоки являются «диффами», которые нужно применить последовательно, чтобы получить текущее состояние БД.

Блокчейн в TON: что это и зачем?

В комментариях задали вопрос: а зачем вообще нужна такая структура данных, когда у нас уже есть DHT — распределённая хэш-таблица? Как упоминалось в предыдущей статье, блокчейн — это структура данных, элементы (блоки) которой упорядочены в «цепь», и каждый следующий блок цепи содержит в себе хэш предыдущего. Балансы криптовалюты хранить в DHT нельзя — в первую очередь из-за отсутствия проверок на целостность. Очевидно, что какие-то данные можно хранить и в DHT, но это подходит только для не слишком «чувствительной» информации. Собственно, вся сложность структуры блокчейна вырастает ради предотвращения вмешательств в хранимые в нём данные.

Первая — стремление минимизировать потребность в форках. Однако блокчейн в TON выглядит ещё сложнее, чем в большинстве других распределённых систем — и на то есть две причины. Вторая причина — поддержка дробления (шардинга, шардирования) блокчейна. В традиционных криптовалютах все параметры заданы на начальном этапе и любая попытка их изменить приводит фактически к появлению «альтернативной вселенной криптовалюты». В традиционных (централизованных) системах для решения подобных проблем применяется шардирование: часть записей в БД находится на одном сервере, часть — на другом, и т.д. Блокчейн — структура, не способная стать меньше с течением времени; и обычно каждый узел, отвечающий за работоспособность сети, вынужден хранить её полностью. В случае с криптовалютами такая функциональность пока что довольно редка — в частности, из-за того, что сложно добавить шардирование в систему, где оно не было запланировано изначально.

Каким же образом TON планирует решить обе вышеописанных проблемы?

Содержимое блокчейна. Воркчейны.

Блокчейн

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

  • баланс;
  • код смарт-контракта (только для смарт-контрактов);
  • хранилище данных смарт-контракта (только для смарт-контрактов);
  • статистика;
  • (опционально) публичный ключ для переводов с аккаунта, по умолчанию account_id;
  • очередь исходящих сообщений (сюда они заносятся для пересылки получателю);
  • список последних доставленных этому аккаунту сообщений.

Однако кроме account_id сообщения содержат также 32-битное поле workchain_id — идентификатор т.н. Как было сказано выше, непосредственно блоки состоят из транзакций — сообщений, доставленных различным аккаунтам account_id. Это позволяет иметь несколько независимых друг от друга блокчейнов с разными конфигурациями. воркчейна (workchain, working blockchain). Вероятнее всего, на первых порах других воркчейнов существовать не будет вовсе. При этом workchain_id = 0 считается особым случаем, нулевым воркчейном — именно находящиеся в нём балансы будут соответствовать криптовалюте TON (Grams).

Шардчейны. Infinite Sharding Paradigm.

Разберёмся с шардингом. Но на этом рост количества блокчейнов не останавливается. Представим, что каждому аккаунту (account_id) выделен свой собственный блокчейн — в нём лежат все приходящие ему сообщения — и состояния всех таких блокчейнов хранятся на отдельных узлах.

Конечно, это весьма расточительно: скорее всего, в каждый из этих шардчейнов (shardchain, shard blockchain) транзакции будут поступать очень редко, а мощных узлов понадобится много (забегая вперёд, отмечу, что речь идёт не просто о клиентах на мобильных телефонах — а о серьёзных серверах).

Этот shard_prefix может иметь длину от 0 до 60 бит — и главное, что он может меняться динамически. Поэтому шардчейны объединяют в себе аккаунты по двоичным префиксам их идентификаторов: если шардчейн имеет префикс 0110, то в него попадут транзакции всех account_id, которые начинаются с этих цифр.

Шардчейны

Например, shard_prefix = 0110b расщепится на 01100b и 01101b. Как только в один из шардчейнов начинает поступать чрезмерно много транзакций, работающие над ним узлы по заранее определённым правилам «расщепляют» его на два дочерних — их префиксы будут на один бит длиннее (и для одного из них этот бит будет равен 0, а для другого — 1). В свою очередь, если два «соседних» шардчейна начнут чувствовать себя достаточно вольготно (в течение некоторого времени), они снова сольются воедино.

Это и подразумевает под собой Infinite Sharding Paradigm (парадигма бесконечного шардирования). Таким образом, шардирование делается «снизу вверх» — мы предполагаем, что каждый аккаунт обладает своим шардом, но они — до поры до времени — «склеены» по префиксам.

Говоря формальным языком, каждый шардчейн определяется парой чисел (workchain_id, shard_prefix). Отдельно хочется подчеркнуть, что воркчейны существуют только виртуально — на самом деле, workchain_id это часть идентификатора конкретного шардчейна.

Исправление ошибок. Вертикальные блокчейны.

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

Вертикальный блокчейн

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

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

Казалось бы, если мы допускаем возможность появления некорректного блока в шардчейне, то нельзя не допустить и возможности появления ошибочного корректирующего блока. Можно отдельно пофилософствовать о том, насколько хорошим является решение «менять прошлое». Подробнее о валидаторах, рабочих группах и других ролях узлов я расскажу в следующей статье. Здесь, насколько я могу судить, разница в количестве узлов, которое должно достигнуть консенсуса по поводу новых блоков — над каждым шардчейном будет трудиться относительно небольшая «рабочая группа» узлов (довольно часто меняющая свой состав), а внесение корректирующих блоков потребует согласия вообще всех узлов-валидаторов.

Один блокчейн, чтоб править всеми

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

  • о количестве и конфигурациях воркчейнов;
  • о количестве шардчейнов и их префиксах;
  • о том, какие узлы в данный момент ответственны за какие шардчейны;
  • хэши последних добавленных блоков во все шардчейны.

Благодаря наличию в его блоках хэшей от блоков всех шардчейнов, он делает систему сильно связанной. Как вы уже могли догадаться, все эти вещи записываются в ещё одно хранилище-блокчейн — мастерчейн (masterchain, master blockchain). В том числе это означает, что генерация нового блока в мастерчейне будет происходить непосредственно после генерации блоков в шардчейнах — ожидается, что блоки в шардчейнах будут появляться почти одновременно примерно каждые 5 секунд, а очередной блок в мастерчейне — спустя секунду после этого.

Неужели всё это будут втихомолку делать телефоны миллионов пользователей с установленным на них клиентом Телеграма? Но кто же будет ответственен за реализацию всей этой титанической работы — за пересылку сообщений, выполнение смарт-контрактов, формирование блоков в шардчейнах и мастерчейне, да ещё и проверку блоков на ошибки? Или, быть может, команда Дуровых откажется от идей децентрализации и это будут делать их сервера по-старинке?

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

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть