Перейти к основному содержимому

Оверлейные подсети

warning

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

Реализация:

Общие сведения

Архитектура TON построена таким образом, что в ней одновременно и независимо может существовать множество цепочек — они могут быть как частными, так и общедоступными. Узлы имеют возможность выбирать, какие шарды и цепочки они хранят и обрабатывают. При этом протокол связи остается неизменным из-за своей универсальности. Такие протоколы, как DHT, RLDP и Оверлеи, позволяют этого добиться. С первыми двумя мы уже знакомы, в этом разделе мы узнаем, что такое Оверлеи.

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

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

ADNL против оверлейных сетей

В отличие от ADNL, оверлейные сети TON обычно не поддерживают отправка датаграмм на другие произвольные узлы. Вместо этого между определенными узлами устанавливаются некоторые “полупостоянные соединения” (называемые “соседними” по отношению к рассматриваемой оверлейной сети), и сообщения обычно пересылаются по этим соединениям (т.е. от узла к одному из его соседей).

Каждая оверлейная подсеть имеет 256-разрядный сетевой идентификатор, обычно равный SHA256 описания оверлейной сети — TL-сериализованного объекта.

Оверлейные подсети могут быть общедоступными или частными.

Оверлейные подсети работают по специальному протоколу gossip.

Взаимодействие с оверлейными узлами

Мы уже разбирали пример с поиском оверлейных узлов в статье о DHT, в разделе Поиск узлов, хранящих состояние блокчейна. В этом разделе мы сосредоточимся на взаимодействии с ними.

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

Найдите больше соседей

Давайте рассмотрим пример получения узлов в оверлее.

Для этого отправьте запрос overlay.getRandomPeers на любой известный узел оверлея, сериализуйте схему TL:

overlay.node id:PublicKey overlay:int256 version:int signature:bytes = overlay.Node;
overlay.nodes nodes:(vector overlay.node) = overlay.Nodes;

overlay.getRandomPeers peers:overlay.nodes = overlay.Nodes;

peers - должен содержать известные нам пиры, поэтому мы не получаем их обратно, но поскольку мы пока не знаем ни одного, peers.nodes будет пустым массивом.

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

Каждый запрос внутри оверлея должен иметь префикс TL-схемы:

overlay.query overlay:int256 = True;

overlay должен быть идентификатором оверлея - идентификатором ключа схемы tonNode.ShardPublicOverlayId - тем же, который мы использовали для поиска в DHT.

Нам нужно объединить 2 сериализованные схемы, просто объединив 2 сериализованных байтовых массива, overlay.query будет первым, overlay.getRandomPeers - вторым.

Мы оборачиваем полученный массив в схему adnl.message.query и отправляем ее через ADNL. В ответе ждем overlay.nodes - это будет список узлов оверлея, к которым мы можем подключиться и, при необходимости, повторить тот же запрос к новым из них, пока не получим достаточное количество подключений.

Функциональные запросы

После того, как соединение установлено, мы можем получить доступ к оверлейным узлам с помощью запросов tonNode.*.

Для запросов такого рода используется протокол RLDP. И важно не забыть префикс overlay.query - он должен использоваться для каждого запроса в оверлее.

В самих запросах нет ничего необычного, они очень похожи на то, что мы делали в статье про ADNL TCP.

Например, запрос downloadBlockFull использует уже знакомую схему идентификатора блока:

tonNode.downloadBlockFull block:tonNode.blockIdExt = tonNode.DataFull;

Передав его, мы сможем загрузить полную информацию о блоке, в ответ получим:

tonNode.dataFull id:tonNode.blockIdExt proof:bytes block:bytes is_link:Bool = tonNode.DataFull;
or
tonNode.dataFullEmpty = tonNode.DataFull;

Если присутствует, поле block будет содержать данные в формате TL-B.

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

Ссылки

Вот ссылка на оригинальную статью Олега Баранова.