Азбука Libp2P От Textile (Или Почему Мы Ее Любим)

Перевод статьи начальный уровень в блоге проекта Текстиль от 19 ноября 2019 г.

Первые шаги по созданию децентрализованного приложения могут оказаться трудными.

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

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

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



Быстро растущая сложность

Реализация распределенной (p2p) связи в любом приложении — непростая задача.

Просто представьте на пару минут, как должно работать ваше творение – и все начинает усложняться прямо на ваших глазах.

Давайте рассмотрим две основные проблемы p2p-приложений: состояние приложения И инфраструктура взаимодействия .

Управление текущим состоянием системы – задача нетривиальная.

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

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

Подумайте над следующими темами, касающимися удаленных узлов:

  • У них ненадежное оборудование и сеть.

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

  • Их могут блокировать брандмауэры или они могут находиться в сетях NAT.
  • Возможно, они используют более старые версии приложений.

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

Даже если вам удастся выпустить первую версию приложения, насколько легко будет изменить что-то позже, не вызывая при этом особых сбоев? Не правда ли, было бы здорово иметь какую-нибудь библиотеку, которая облегчила бы нашу задачу?!

Libp2p приходит на помощь!

Libp2p — это библиотека, созданная в результате работы Протокольные лаборатории выше ИПФС .

Если вы вообще следили за нашим блогом, то знаете, что мы его большие поклонники! Когда вы берете на себя задачу написать с нуля промышленное p2p-приложение, вы понимаете, что создаете не только приложение, но и его инфраструктуру — и до вас быстро доходит, что нужно изобретать кучу дополнительных колес.

Хотя это не весело.

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

Теперь это веселее! Конечно, libp2p не является панацеей от всех наших p2p-монстров, но она, безусловно, облегчает бремя реализации инфраструктуры совместимости.



Основные понятия Libp2p

Ядром libp2p является объект Хозяин ( Хозяин ), который представляет наш локальный узел в p2p-сети.

Общее описание его компонентов:

  • Идентификатор, по которому наш узел распознается другими узлами.

  • Набор местных адресов, по которым вы можете связаться с нами.

  • Журналы информации о других узлах: их идентификаторы, ключи, адреса и т.д.
  • Сетевой интерфейс для управления соединениями с другими узлами.

  • Мультиплексор, который позволяет одному соединению работать с несколькими протоколами (подробнее об этом позже).

Следующая базовая абстракция в libp2p — это Потоки .

Поток ( Транслировать ) — прямой канал связи с другим узлом.

Важно понимать разницу между Транслировать и «сырой» сетевой протокол, такой как TCP или UDP — ведь именно здесь раскрывается вся мощь libp2p: самостоятельно сетевые протоколы — всего лишь средство отправки байтов по сети.

Если вам нужна высокая надежность доставки пакетов, вы можете использовать TCP; в других случаях UDP может быть предпочтительнее.

Короче говоря, сами сетевые протоколы не заботятся о том, какие данные они передают; для них это просто байты.

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

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

Этот протокол помечен идентификатором, например /sumtwointegers/v1.0.0. А ты Транслировать - диалог в рамках настоящего протокола.

Например, одна сторона отправляет два целых числа, а другая отвечает их суммой.

Это то, что мы подразумеваем под поток байтов с семантикой .

Потоки работать поверх сетевых протоколов, таких как TCP или UDP. По сути, идея состоит в том, чтобы отдельный p2p-коммуникация по сетевым протоколам (нижний уровень).

Нам остается только подумать о прикладном использовании потокового канала — для отправки осмысленной информации, а в него уже заложена гибкость работы по любому сетевому протоколу, доступному между узлами (в Транслировать ).

Это действительно круто и мощно.

А это также означает, что мы можем оптимизировать функциональность отдельно на каждом уровне.

куча .

Нужна лучшая реализация сетевого протокола? Отлично, оставьте это libp2p. Более семантически выразительный дизайн протокола p2p? Круто, это тоже! Более того, отделение семантики p2p от базовых сетевых протоколов позволяет libp2p идти дальше и мультиплекс Потоки в том же сетевом протоколе.

Мы можем использовать одно и то же TCP-соединение для многих Потоки .

Мы можем запустить протокол умножения двух целых чисел на том же соединении, на котором запускались наши протоколы суммирования двух целых чисел.

Но Потоки Вам не придется справляться с этим самостоятельно.

На самом деле Libp2p опирается на мультиплексоры ( "Мультиплексоры" ), чтобы совершить это волшебство.

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

Вот краткая диаграмма, которая немного это объясняет.

Азбука libp2p от Textile (или почему мы ее любим)

Как мы видели выше, наши Хоста Есть Муксер , который мультиплексирует (объединяет) множество потоков одного и того же узла в одном соединении.

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

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

блокировка заголовка .

Альтернативно, сам транспорт (основной сетевой протокол) может включать полностью реализованный механизм мультиплексирования (например, QUIC ).

Но это уже другой разговор.



Делаем шаг назад

Попробуем разобраться, о чем идет речь Мы следует подумать при написании приложения, из-за того, что libp2p делает для нас .

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

Мы должны думать о взаимодействии узлов, а не об адресах.

А затем просто реализовать намеченное взаимодействие на уровне абстракции.

Транслировать .

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

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

Умно, однако! Она, libp2p, может определить, что нет необходимости подключаться повторно, если у нас уже есть открытое соединение.

Когда мы запустим новый Поток при связи с определенным узлом мультиплексор выполняет рутинную работу по объединению его с другими существующими узлами.

Потоки в уже установленном соединении.

Зачем так стремиться к многократному использованию одного соединения? Возможно, нашим p2p-приложениям придется работать в очень ограниченных сетевых средах, где существуют брандмауэры.

НАТ и ограничения на количество подключений.

Поэтому, как только мы установим связь, мы должны извлечь из нее максимум пользы! Приняв образ мышления p2p, вы можете столкнуться со многими неизвестными, поэтому использование libp2p поможет вам сосредоточиться на хорошем дизайне, даже если вы не являетесь экспертом.



Но это еще не все!

Libp2p был разработан как модульная библиотека.

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

Я думаю, что обоснование такого подхода – помимо хорошей инженерной практики – свидетельствует о разнообразии сред, в которых будет работать наше приложение.

И вы можете быть уверены, что именно так обстоит дело и с p2p-приложениями.

Наша программа сможет работать в самых разных средах выполнения с различными сетевыми возможностями или ограничениями.

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

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

Нам необходимо выяснить, какой сетевой транспорт используют оба собеседника (TCP, UDP, QUIC, Websockets), какие версии протоколов мы можем обрабатывать( /мипротокол/v1.0.0, /мипротокол/v1.1.0 ), какие реализации мультиплексора мы можем использовать, нам нужно согласовать параметры безопасности и т. д. И если этого недостаточно, в libp2p есть целый набор встроенных протоколов для решения множества повседневных задач p2p-приложений, таких как:

  • NAT Traversal: это больное место для p2p-приложений.

  • Обнаружение узлов в сети.

    Действительно, как обнаружить новые узлы вне централизованной модели?

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

  • И многие-многие другие!
Небольшой бонус: Libp2p растет очень быстро, поэтому вы можете ожидать появления новых мощных инструментов, которые можно будет использовать с небольшим количеством специального кода.

Помните, что приложения p2p должны быть разными, поэтому libp2p будет иметь разные функции в разных языковых реализациях.

Например, некоторые реализации мультиплексора могут быть недоступны в JS, но вполне возможны в Go или Rust.

Давайте подведем итоги

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

Мы можем сосредоточиться на создании функциональности приложения и позволить libp2p выполнять инфраструктурные задачи.

Более того, дальнейшие улучшения libp2p улучшат наше приложение, не затрагивая его бизнес-логику.

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

Также, если вы заинтересованы в таких вещах или хотите интегрировать p2p-коммуникацию в свое приложение или проект, Связаться с нами , и давайте экспериментировать вместе! Вы также можете попробовать один из «легкие» библиотеки если вам нужен простой способ использования узла libp2p в браузере, iOS, Android и/или на рабочем столе.

Наконец, если вам нравятся подобные обзорные статьи, дайте нам знать или запросите дополнительные темы.

а пока удачного программирования! Автор оригинального текста: Игнасио Агопян Перевод: Алексей Силин ( СтарВер ) Теги: #Децентрализованные сети #с открытым исходным кодом #Распределенные системы #P2P #IPFS #libp2p #libp2p

Вместе с данным постом часто просматривают: