Skip to main content

Основы распределённого реестра

Раздел посвящён низкоуровневому техническому обзору распределённого реестра с модернизированным алгоритмом быстрого и масштабируемого консенсуса по свойствам соответствующий семейству византийских соглашений с закрытым уровнем доступа, который применяется для Платежей, Клиринга и расчётов в TKEY7.

Распределённый реестр — детерминированный асинхронный конечный автомат, состояние которого реплицируется на N компьютеров (узлов), и действует как единый конечный автомат. Одно и то же «Состояние + Ввод» всегда создаёт одно и то же следующее «Состояние + Вывод».

Состояние
  • Хранение на разных физических компьютерах.
  • Запуск функции с такими же данными: «Ввод + Состояние».
  • Запуск в одно и то же время — синхронно.
  • Выдача тех же данных: «Вывод + следующее Состояние».

Репликация предназначается для надёжности и децентрализации, реплики координируются алгоритмом консенсуса, что обеспечивает одинаковое текущее состояние и вводные данные во всех репликах.

Репликация

Конечный автомат на уровне Распределённого реестра

  • Реестр — это данные Состояния на текущий момент времени.
  • Транзакции — это данные Ввода (подлинные инструкции, которые необходимо выполнить).
  • Архивы — это данные Вывода (журнал изменений во время каждого перехода в Состояние).
Состояние распределённого реестра

Узлы следует бесконечному циклу каждые 3–6 секунд.

Цикл в контексте Конечного автоматаЦикл в контексте Распределённого реестра
Достигает консенсуса в отношении Состояния и Ввода.Достигает консенсуса в отношении Реестра и Транзакций.
Применяет Ввод к Состоянию.Применяет Транзакции к Реестру.
Производит Вывод и переходит в новое Состояние.Публикует Архив и переходит к новому Реестру.

Реестры

Конечный автомат формирует новый реестр каждые 3–6 секунд, создавая непрерывную цепочку связанных между собой реестров. Распределённый реестр поддерживает содержимое последнего реестра и цепочки реестров в нескольких представлениях данных. Текущий реестр хранится в локальной базе данных SQL для обеспечения ACID-безопасности, данные которого сопряжены с каждым процессом программы Распределённого реестра. Консенсус касается только настоящего, обращение к базе данных и обновление выполняется в режиме реального времени. Для применения согласованного набора транзакций используются только текущие данные и хеш-значение предыдущего реестра.

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

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

Типы записей реестра

Тип записиОписание
Учётная записьСтруктура системно значимых данных в распределённом реестре, которая обеспечивает учёт остатков, подпись транзакций, выпуск активов и контроль авторизации активов, учитываемых в Распределённом реестре.
Кредитная линияЗаписи, которые определяют условия использования актива.
ПредложенияЗапись о покупке или продаже активов, которые создаются Учётной записью в Распределённом реестре. Записи используются для автоматизации торговой функциональности.
МетаданныеЗаписи, которые представлены в виде связки «ключ-значение» и принадлежат определённой Учётной записи. Этот тип записи позволяет владельцу Учётной записи добавлять метаданные к Учётной записи для определённых целей.

Транзакции

Транзакция — SQL-команда изменения состояния реестра, которая может содержать одну или несколько инструкций.

  • Каждая транзакция имеет порядковый номер, который связан с Учётной записью.
  • Транзакции содержат одну или массив инструкций, которые требуется применить к текущему реестру, и выполняются в соответствии с ACID.
  • Транзакции подписывается одной или несколькими цифровыми подписями.
  • Транзакции формируются в набор транзакций и применяются к реестру.

Сущность Транзакции

ЗначениеОписание
Учётная записьИдентификатор учётной записи инициатора транзакции.
КомиссияКомиссия за транзакцию, которая измеряется в сетевом ресурсе и рассчитывается на основе количества инструкций в транзакции умноженных на базовую комиссию сети.
Порядковый номерПорядковый номер транзакции инициатора. По умолчанию порядковый номер транзакции равен порядковому номеру Учётной записи + 1.
Список инструкцийОдна или несколько инструкций: перевод (передача актива в пределах суммы остатков от одной Учётной записи в другую), изменение списка подписантов, изменение кредитной линии и другие. Инструкции выполняются атомарно, применяются либо все инструкции в транзакции, либо ни одной.
Список подписейОдна или несколько электронных подписей.
ЗаметкаЦелое, строковое или хеш-значение. Заметка применяется для включения в транзакцию дополнительной информации.
Условия достоверностиДополнительные параметры для включения транзакции в реестр.

Условия достоверности

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

Модель хранения

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

Форматы данных

Распределённый реестр работает с данными в 4 местах и хранит реестры в XDR и SQL — одновременно.

XDRSQL
Транзакции (Ввод), полученные в XDR.Реестр (Состояние)
Реестр (Состояние) хранящийся на диске в XDR.Часть Архивов (Вывод)
Архивы (Вывод), передаваемые в XDR.Чтение/Запись при применении Транзакций (Ввод).
Все сетевые P2P-сообщения и сообщения Консенсуса.Консенсус выполняет чтение, чтобы проверить потенциальный Ввод.

Места работы с данными

Таблицы SQL в реляционной базе данных:

Обращение к базе данных в процессе консенсуса.

  • Атомарные изменения Состояния конечного автомата.

XDR между репликами конечного автомата:

Хранение в памяти до достижения консенсуса.

  • P2P-сообщения между узлами.
  • Транзакции и сообщения консенсуса.

XDR в локальном хранилище:

Хранение реестра в канонической форме — плоские XDR-файлы и дублирование данных, хранящихся в таблицах SQL.

  • Эффективное, инкрементное криптографическое хеширование.
  • Эффективное, инкрементное хранение и передача различий.

XDR в публичных архивах:

Хранение контрольных точек и журналов архивов. Один JSON-файл перезаписывается, чтобы указать на текущую контрольную точку.

  • Быстрая синхронизация реестров.

Движение данных в 5 потоках

  1. Публичные архивы - - - > Узлы = «Навёрстывание».
  2. Внешние клиенты - - - > Узлы = «Отправление».
  3. Узлы - - - > Узлы = «Затопление».
  4. Узлы - - - > Базы данных и локальные файлы = «Применение».
  5. Узлы - - - > Публичные архивы = «Публикация».
Поток данных

Навёрстывание

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

  • Загрузка XDR-файлов из публичного архива.
  • Один из двух выбранных режимов узлом:
    • Воспроизводит переходы состояний по порядку.
    • Привязывается к последнему состоянию, в этом режиме загружаются только различия.

Отправление

Выполняется, когда у внешнего клиента появляется новая транзакция.

  • Контактирует с узлами через HTTP-узел — Службу коннектора.
  • Отправляет XDR-представление транзакции.
  • Получает код состояния: «отклонено» или «ожидается».

Затопление

Выполняется непрерывно в оверлейной сети.

  • Узлы поддерживают друг с другом долговременные TCP-соединения.
  • Все сообщения передаются в закодированном XDR-представлении и повторяются для всех узлов.
  • Транзакции поступают по мере их отправки.
  • Сообщения консенсуса — всплеск активности каждые 3–6 секунд.

Применение

Выполняется, когда протокол принимает решение о согласованном Состоянии (состояние консенсуса) + Вводные данные. Цикл: каждые 3–6 секунд.

  • Транзакции в памяти применяются к реестру в базе данных SQL.
  • Дубликаты изменённых записей реестра помещаются в сегменты.
  • Транзакции и результаты записываются в накопительную контрольную точку.

Публикация

Выполняется каждые 64 записи реестра.

  • Узлы загружают накопленные контрольные точки в публичные архивы.
  • Архив включает 64 перехода между состояниями в сжатом виде.
  • Узлы отправляют только сегменты, которые отличаются от предыдущих контрольных точек.

Состояние реестра сохраняется следующими способами:

  1. Реляционная база данных PostgreSQL — используется отдельный сервер, изолированный по запросам: узел-валидатор — сервер БД.
  2. Локальное хранилище двоичных файлов — используются SSD-диски или управляемые файловые хранилища с высокой производительностью.
  3. Публичные архивы — используются зарекомендовавшие решения с предсказуемым профилем: Yandex Cloud, VK Cloud Solutions, AWS S3, Google Cloud Storage, Azure Blob Storage, включая собственные SCP/SFTP-сервера. Публичные архивы используют PUT и GET-запросы.
БД SQLЛокальное хранилищеПубличные архивы
Горячее хранилище данных.Холодное хранилище. Хранение записей реестра в линеаризованном формате с использованием определённого расположения сегментов экспоненциально большего размера.Долгосрочное хранилище. Хранение согласованного журнала транзакций и набора снимков реестра в канонической форме: сжатые XDR-файлы.
Поддержка ACID-состояния.Быстрое вычисление хеша нового реестра. Эффективно вычисляет единый хеш быстро меняющейся базы данных, без необходимости повторного хеширования базы данных при каждом её изменении.Непрерывное резервное копирование за счёт получения новых реестров от валидаторов.
Отправка запросов о состоянии текущего реестра на HTTP-узлы.Предоставление данных о текущем состоянии реестра узлам, которые отстают — дешёвая операция, когда узел был отключён в течение определённого периода времени и необходимо быстро синхронизировать базу данных с текущим реестром.Предоставление данных новым и отстающим узлам.

Локальное хранилище

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

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

Список сегментов хранит записи реестров на диске для хеширования и дедупликации данных. Модуль списка сегментов координирует хеширование и дедупликацию сегментов несколькими фоновыми потоками. Окончательная дельта, полученная после закрытия реестра, передаётся для добавления в локальное хранилище — L0. Полученный набор записей используется для вычисления хеша всего набора записей реестра.

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

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

Публичные архивы

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

Публичные архивы позволяют выполнять функцию «навёрстывания» отстающим или новым узлам, для этого узлы-валидаторы сохраняют контрольные точки в XDR-файлах, затем сжимают файлы и публикуют их в публичных архивах, такая операция выполняется каждые 6 минут.

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

Публичные архивы выполняют следующие функции:

  • Обеспечение надёжного резервного копирования.
  • Минимизация рисков отказа одного узла.
  • Изоляция догоняющей нагрузки ввода-вывода от P2P-наводнения.
  • Обеспечение лёгкого доступа к данным.

Архитектура

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

  • Используется единый стандарт XDR для канонического формата реестров, транзакций, архивов, P2P-сообщений.
  • Не применяются пользовательские типы данных — отсутствуют временные эпохи, коды валют, десятичные числа с плавающей точкой и другие.
  • Отсутствует прямое обслуживание общедоступных HTTP-запросов. HTTP-интерфейсы и Websocket находятся на отдельных серверах.
  • Отсутствует вторичный процесс контроля, нет автономных потоков и сложных запросов на завершение работы.
  • Отсутствует многопоточность в основной логике ввода-вывода или консенсуса. Один основной поток выполняет асинхронный ввод-вывод и формирует консенсус.
  • Несколько рабочих потоков выполняют вычисления: в первую очередь memcpy, сериализацию, хеширование.
  • Отсутствуют таймауты в режиме реального времени, за исключением синхронизации виртуального и реального времени в производственной среде. Виртуализированное время позволяет переводить сервер в быстрое имитируемое время.
  • Позволяет запускать нескольких экземпляров программы в процессе и соединять их для тестирования обратной связи.
  • Хранилище разделено на две части: одно хранилище на основе объёмного (локального хранилища) и холодного хранилища (публичных архивов), которое хранится в плоских XDR-файлах, и одно горячее — индексируемое хранилище база данных SQL.

Криптомодуль содержит программные «обёртки» вокруг библиотеки — Libsodium для создания ключевой пары, шифрования, дешифрования и хеширования данных, и также реализацию преобразования ключевой пары в удобочитаемый формат — строку.

На уровне Распределённого реестра используется алгоритм EdDSA в качестве механизма цифровой подписи и протокол ECDH для применения сеансовых экземпляров curve25519-ключей между узлами.

Электронная подпись

Учётная запись в Распределённом реестре состоит из секретного и публичного ключа. Для создания Учётной записи и подписи транзакций используется криптография с открытым ключом, с помощью которой создаются экземпляры Ed25519-ключей. Только подписанные транзакции могут быть включены в реестр.

Сеансовые ключи

В качестве ключей аутентификации между узлами используются Curve25519-ключи, которые рандомизируются при запуске и применяются только для «протокола согласования ключей» между узлами. Ключи curve25519 выступают, как временные ключи, которые используются для каждого сеанса и подписываются Ed25519-ключами во время «рукопожатия» Узлов.

Подключение узлов:

  • Узел A инициирует TCP-соединение с узлом B.
  • Как только соединение установлено, узел A посылает — сообщение Приветствия (CertA, NonceA), содержащее порт прослушивания узла А и информацию о реестре.
  • Узел B получает IP-адрес и порт прослушивания узла A, и в ответ посылает сообщение Приветствия (CertB, NonceB).
  • Узел A отправляет сообщение Аутентификации (подписанные данные ([Sequence], KeyAB))
  • Узел B проверяет сообщение Аутентификации от узла A и делает следующее:
    • отправляет сообщение Аутентификации (подписанные данные([Sequence], KeyBA)) обратно,
    • отправляет список других узлов для попытки соединения,
    • разъединяется, если нет доступных слотов для подключения.
  1. KeyAB и KeyBA — это ключи HMAC для каждого соединения, полученные из неинтерактивного ECDH на случайных curve25519-ключах, передаваемых в CertA и CertB, результат которых передаётся через функцию HKDF с однократно используемыми числами: nonceA и nonceB для каждого соединения.
  2. CertA и CertB — сертификаты, подписанные Ed25519-ключами узлов А и В.
  3. NonceA и NonceB — однократно используемые числа для каждого соединения.
  4. Sequence — счётчик для предотвращения повторов сообщений.

Заголовок реестра

ПолеОписание
ВерсияВерсия протокола.
Идентификатор предыдущего реестраХеш-значение предыдущего реестра.
Идентификатор набора транзакцийХеш-значение набора успешных транзакций в предыдущем реестре.
Время закрытия реестраМетка времени закрытия предыдущего реестра.
Результат транзакцийХеш-значение результатов набора транзакций.
Список сегментовХеш-значение объектов текущего состояния реестра.
Порядковый номер реестраПорядковый номер текущего реестра.
Количество КвотыОбщее количество сетевого ресурса.
Количество транзакцийКоличество транзакций, обработанных узлами-валидаторами в текущем реестре.
Базовая комиссияМинимальная установленная базовая комиссия за транзакцию в текущем реестре, которая измеряется в сетевом ресурсе.
РезервМинимальный установленный резерв сетевого ресурса в текущем реестре, который должен содержаться в Учётной записи.

Сущность учётной записи

ЗначениеОпределение
Ключевая параНабор значений, состоящий из секретного ключа и публичного ключа, вычисление которых выполняются одновременно посредством односторонней криптографической хеш-функции публичного ключа Участника. Таким образом, ключевая пара определяется, как криптографические ключи, которые создаются на основании криптографических алгоритмов и представляются в виде строк случайных букв и цифр верхнего регистра.
Идентификатор учётной записиПубличный ключ, представленный в виде уникальной последовательности символов, которая соответствует секретному ключу — вместе ключи образуют Ключевую пару, связанную между собой математическим соответствием. В контексте TKEY7 идентификатор Учётной записи, определяется как Адрес счёта и предназначается для однозначной идентификации Цифрового счёта Участника с Учётной записью в Распределённом реестре.
Порядковый номерТекущий порядковый номер транзакции. Последовательность порядкового номера устанавливается с номера Реестра, под номером которого создана Учётная запись и увеличивается в последовательности по мере, когда Учётная запись подписывает транзакции.
Время порядкового номера и номер реестраЗначения метки времени закрытия реестра и время запроса порядкового номера, которые определяют время, когда исходная Учётная запись запрашивала порядковый номер для инициации транзакции. Используется для установления порядкового номера.
Количество субзаписейЗначение, которое используется для расчёта минимальных резервов Сетевого ресурса. Субзаписи включают: кредитные линии, предложения, подписантов, метаданные. В контексте Учётной записи, — субзаписи выступают в качестве надстроек.
Количество обеспеченных субзаписейЗначение, которое определяет количество субзаписей, принадлежащих Учётной записи и обеспеченных другой Учётной записью.
Количество обеспеченных субзаписей текущей Учётной записьюЗначение, которое определяет количество субзаписей, обеспеченных текущей Учётной записью.
Пороговое значениеЗначение, представляющее показатель величины подписи, которое требуется для успешного выполнения определённой операции в Распределённом реестре. Таким образом, для выполнения операции требуется, чтобы суммарная величина подписи соответствовала пороговому значению, которое требует операция для авторизации.
ДоменURL-адрес домена Участника TKEY7.
Флаговое значениеЗначение, которое устанавливает уровень авторизации к Эмиссионному активу. Значение устанавливается во время установления Кредитной линии и необходимо для контроля доступа к Активам.
ОстаткиКоличество единиц Активов, которыми владеет Учётная запись.
ОбязательстваСумма обязательств по Предложениям покупки или продажи актива, инициированных текущей Учётной записью.
ПодписантыПоле, содержащее Идентификаторы учётных записей и Пороговые значения, которые используются для авторизации транзакций.
Page last updated: 26 November 2022