- PVSM.RU - https://www.pvsm.ru -
Данный текст — продолжение серии статей, в которых я рассматриваю структуру (предположительно) готовящейся к выходу в этом году распределенной сети Telegram Open Network (TON). В предыдущей части [1] я описал её самый базовый уровень — способ взаимодействия узлов между собой.
На всякий случай напомню, что к разработке этой сети я отношения не имею и весь материал почёрпнут из открытого (хотя и непроверенного) источника — документа [2] (ещё к нему есть прилагающаяся брошюра [3], излагающая вкратце основные моменты), появившегося в конце прошлого года. Объем информации в этом документе, на мой взгляд, свидетельствует о его подлинности, хотя никаких официальных подтверждений тому нет.
Сегодня посмотрим на основной компонент TON — блокчейн.
Аккаунт (account). Некий набор данных, идентифицируемый 256-битным числом account_id (чаще всего это публичный ключ владельца аккаунта). В базовом случае (см. ниже нулевой воркчейн), под этими данными подразумевается баланс пользователя. «Занять» конкретный account_id может кто угодно, но изменять его значение можно только по определённым правилам.
Смарт-контракт (smart-contract). По сути — частный случай аккаунта, дополненный кодом смарт-контракта и хранилищем его переменных. Если в случае «кошелька» можно зачислять и списывать деньги из него по относительно простым и заранее определённым правилам, то в случае смарт-контракта эти правила записаны в виде его кода (на некоем Тьюринг-полном языке программирования).
Состояние блокчейна (state of blockchain). Совокупность состояний всех аккаунтов/смарт-контрактов (в абстрактном смысле — хэш-таблица, где ключами являются идентификаторы аккаунтов, а значениями — хранимые в аккаунтах данные).
Сообщение (message). Выше я употребил выражение «зачислять и списывать деньги» — это частный пример сообщения («передать N грамм с аккаунта account_1 на аккаунт account_2»). Очевидно, отправить такое сообщение может только узел, владеющий закрытым ключом аккаунта account_1 — и способный подтвердить это подписью. Результатом доставки таких сообщений обычному аккаунту является увеличение его баланса, а смарт-контракту — выполнение его кода (который обработает прием сообщения). Разумеется, возможны и другие сообщения (переносящие не денежные суммы, а произвольные данные между смарт-контрактами).
Транзакция (transaction). Факт доставки сообщения называется транзакцией. Транзакции изменяют состояние блокчейна. Именно из транзакций (записей о доставке сообщений) состоят блоки в блокчейне. В этом плане можно представлять себе состояние блокчейна как инкрементальную базу данных — все блоки являются «диффами», которые нужно применить последовательно, чтобы получить текущее состояние БД. О конкретике упаковки этих «диффов» (и восстановлении полного состояния по ним) пойдёт речь в следующей статье.
Как упоминалось в предыдущей статье, блокчейн — это структура данных, элементы (блоки) которой упорядочены в «цепь», и каждый следующий блок цепи содержит в себе хэш предыдущего. В комментариях задали вопрос: а зачем вообще нужна такая структура данных, когда у нас уже есть DHT — распределённая хэш-таблица? Очевидно, что какие-то данные можно хранить и в DHT, но это подходит только для не слишком «чувствительной» информации. Балансы криптовалюты хранить в DHT нельзя — в первую очередь из-за отсутствия проверок на целостность. Собственно, вся сложность структуры блокчейна вырастает ради предотвращения вмешательств в хранимые в нём данные.
Однако блокчейн в TON выглядит ещё сложнее, чем в большинстве других распределённых систем — и на то есть две причины. Первая — стремление минимизировать потребность в форках. В традиционных криптовалютах все параметры заданы на начальном этапе и любая попытка их изменить приводит фактически к появлению «альтернативной вселенной криптовалюты». Вторая причина — поддержка дробления (шардинга, шардирования) блокчейна. Блокчейн — структура, не способная стать меньше с течением времени; и обычно каждый узел, отвечающий за работоспособность сети, вынужден хранить её полностью. В традиционных (централизованных) системах для решения подобных проблем применяется шардирование: часть записей в БД находится на одном сервере, часть — на другом, и т.д. В случае с криптовалютами такая функциональность пока что довольно редка — в частности, из-за того, что сложно добавить шардирование в систему, где оно не был запланировано изначально.
Каким же образом TON планирует решить обе вышеописанных проблемы?
В первую очередь, поговорим о том, что же планируется хранить в блокчейне. Храниться там будут состояния аккаунтов («кошельков» в базовом случае) и смарт-контрактов (для простоты будем считать, что это то же, что и аккаунты). По сути, это будет обычная хэш-таблица — ключами в ней будут идентификаторы account_id, а значениями — структуры данных, содержащих в себе такие вещи, как:
Как было сказано выше, непосредственно блоки состоят из транзакций — сообщений, доставленных различным аккаунтам account_id. Однако кроме account_id сообщения содержат также 32-битное поле workchain_id — идентификатор т.н. воркчейна (workchain, working blockchain). Это позволяет иметь несколько независимых друг от друга блокчейнов с разными конфигурациями. При этом workchain_id = 0 считается особым случаем, нулевым воркчейном — именно находящиеся в нём балансы будут соответствовать криптовалюте TON (Grams). Вероятнее всего, на первых порах других воркчейнов существовать не будет вовсе.
Но на этом рост количества блокчейнов не останавливается. Разберёмся с шардингом. Представим, что каждому аккаунту (account_id) выделен свой собственный блокчейн — в нём лежат все приходящие ему сообщения — и состояния всех таких блокчейнов хранятся на отдельных узлах.
Конечно, это весьма расточительно: скорее всего, в каждый из этих шардчейнов (shardchain, shard blockchain) транзакции будут поступать очень редко, а мощных узлов понадобится много (забегая вперёд, отмечу, что речь идёт не просто о клиентах на мобильных телефонах — а о серьёзных серверах).
Поэтому шардчейны объединяют в себе аккаунты по двоичным префиксам их идентификаторов: если шардчейн имеет префикс 0110, то в него попадут транзакции всех account_id, которые начинаются с этих цифр. Этот shard_prefix может иметь длину от 0 до 60 бит — и главное, что он может меняться динамически.
Как только в один из шардчейнов начинает поступать чрезмерно много транзакций, работающие над ним узлы по заранее определённым правилам «расщепляют» его на два дочерних — их префиксы будут на один бит длиннее (и для одного из них этот бит будет равен 0, а для другого — 1). Например, shard_prefix = 0110b расщепится на 01100b и 01101b. В свою очередь, если два «соседних» шардчейна начнут чувствовать себя достаточно вольготно (в течение некоторого времени), они снова сольются воедино.
Таким образом, шардирование делается «снизу вверх» — мы предполагаем, что каждый аккаунт обладает своим шардом, но они — до поры до времени — «склеены» по префиксам. Это и подразумевает под собой Infinite Sharding Paradigm (парадигма бесконечного шардирования).
Отдельно хочется подчеркнуть, что воркчейны существуют только виртуально — на самом деле, workchain_id это часть идентификатора конкретного шардчейна. Говоря формальным языком, каждый шардчейн определяется парой чисел (workchain_id, shard_prefix).
Традиционно считается, что любая транзакция в блокчейне является «высеченной в камне». Однако, в случае с TON предусмотрена возможность «переписать историю» — в случае, если некто (т.н. узел-«рыбак») докажет, что один из блоков был подписан некорректно. В этом случае в соответствующий шардчейн добавляется специальный корректирующий блок, содержащий хэш самого исправляемого блока (а не последнего блока в шардчейне). Представляя шардчейн как цепочку блоков, выложенную по горизонтали, можно сказать, что корректирующий блок подцепляется к ошибочному блоку не вправо, а сверху — поэтому считается, что он становится частью маленького «вертикального блокчейна». Таким образом, можно сказать, что шардчейны являются двумерными блокчейнами.
В случае если после ошибочного блока на внесённые им изменения ссылались последующие блоки (т.е., были совершены новые транзакции на основе невалидных), к этим блокам так же «сверху» добавляются корректирующие. Если блоки не затрагивали «поражённую» информацию, на них эти «корректирующие волны» не распространяются. Например, в иллюстрации выше некорректной была признана транзакция первого блока, увеличивающая баланс аккаунта C — поэтому транзакция, уменьшающая баланс этого аккаунта в третьем блоке, также должна быть аннулирована, а поверх самого блока закоммичен корректирующий блок.
Надо заметить — хотя корректирующие блоки и изображаются расположенными «над» оригинальными, фактически они будут дописаны в конец соответствующего блокчейна (туда, где должны находиться хронологически). Двумерное расположение лишь показывает, к какой точке в блокчейне они будут «подцеплены» (посредством находящегося в них хэша оригинального блока).
Можно отдельно пофилософствовать о том, насколько хорошим является решение «менять прошлое». Казалось бы, если мы допускаем возможность появления некорректного блока в шардчейне, то нельзя не допустить и возможности появления ошибочного корректирующего блока. Здесь, насколько я могу судить, разница в количестве узлов, которое должно достигнуть консенсуса по поводу новых блоков — над каждым шардчейном будет трудиться относительно небольшая «рабочая группа» узлов (довольно часто меняющая свой состав), а внесение корректирующих блоков потребует согласия вообще всех узлов-валидаторов. Подробнее о валидаторах, рабочих группах и других ролях узлов я расскажу в следующей статье.
Выше перечислено много информации о различных видах блокчейнов, которую саму по себе тоже следует где-то хранить. В частности, речь о следующих сведениях:
Как вы уже могли догадаться, все эти вещи записываются в ещё одно хранилище-блокчейн — мастерчейн (masterchain, master blockchain). Благодаря наличию в его блоках хэшей от блоков всех шардчейнов, он делает систему сильно связанной. В том числе это означает, что генерация нового блока в мастерчейне будет происходить непосредственно после генерации блоков в шардчейнах — ожидается, что блоки в шардчейнах будут появляться почти одновременно примерно каждые 5 секунд, а очередной блок в мастерчейне — спустя секунду после этого.
Но кто же будет ответственен за реализацию всей этой титанической работы — за пересылку сообщений, выполнение смарт-контрактов, формирование блоков в шардчейнах и мастерчейне, да ещё и проверку блоков на ошибки? Неужели всё это будут втихомолку делать телефоны миллионы пользователей с установленным на них клиентом Телеграма? Или, быть может, команда Дуровых откажется от идей децентрализации и это будут делать их сервера по-старинке?
На самом деле, ни тот, ни другой ответ не является правильным. Но поля этой статьи стремительно заканчиваются, поэтому разговор о различных ролях узлов (вы могли уже заметить упоминания некоторых из них), а также о механиках их работы пойдёт уже в следующей части.
Автор: deNULL
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/algoritmy/279882
Ссылки в тексте:
[1] предыдущей части: https://habr.com/post/354366/
[2] документа: https://denull.ru/telegram/ton-tech.pdf
[3] брошюра: https://denull.ru/telegram/ton.pdf
[4] Источник: https://habr.com/post/354568/?utm_campaign=354568
Нажмите здесь для печати.