Network layer
P2P (Peer-to-Peer) Сеть, или Одноранговая Сеть, является децентрализованной структурой, которая распределяет задачи и нагрузку среди участников (пиров). В P2P Сетях, подключенные компьютеры равны друг другу, и каждый узел является как поставщиком, так и потребителем ресурсов, услуг и контента. В отличие от традиционных сетевых моделей Клиент-Сервер, P2P Сети имеют преимущества децентрализации, масштабируемости, устойчивости к атакам и быть приватными. Эти преимущества обеспечивают выполнение операций в блочной цепи, и являются краеугольными камнями свободного, автономного и децентрализованного блокчейна.
Проектирование сетевого уровня IOST
Мы стремимся построить полностью децентрализованную сетевую топологию, с быстрым обнаружением узлов и скоростным вещанием всех внутрисетевых транзакций и блоков. В тоже время, мы надеемся ограничить резервирование сети, и обеспечить безопасную передачу данных между узлами. Благодаря исследованиям и тестированию мы решили использовать мощные libp2p библиотеки в качестве нашего сетевого уровня.
Обнаружение узлов и подключение
Базовый протокол это TCP/IP. С целью предотвращения перехвата и нежелательного манипулирования данными, мы защищаем данные с помощью TLS-уровня поверх TCP. С целью лучше использовать каждое TCP-соединение, мы принимаем потоковое мультиплексирование для отправки и получения данных, динамически устанавливая несколько потоков между узлами и максимизируя пропускную способность.
С узлами мы используем Kademlia, чтобы поддерживать их таблицы шлюзов. Алгоритм Kademlia использует XOR значения между ID узлов для вычисления расстояния между ними. Узлы помещаются в сегменты (k-buckets) в зависимости от их расстояний к другим узлам. Когда запрашивается узел, нам нужно найти ближайший узел в соответствующем сегменте (k-bucket). При определенном числе запросов мы можем гарантировать, что информация будет найдена для узла. Kademlia отличается своей быстротой и универсальностью.
Передача данных
Мы сериализуем все структурированные данные с помощью протокола Buffer и сжимаем их с помощью алгоритма Snappy, чтобы уменьшить пропускную способность и ускорить передачу данных. Во время наших тестов этот подход уменьшил размер данных более чем на 80%.
Трансляция приведет к избыточной передаче данных и, следовательно, потери пропускной способности и мощности обработки. Многие проекты предотвращают неопределенную ретрансляцию данных путем ограничения "прыжков" (или сколько раз определенные данные были ретранслированы). Недостатком этого подхода является то, что определенное количество ретрансляции не может гарантировать охват данных всей сетью, особенно когда сеть огромна. Способ, которым EOS справляется с этой проблемой: сетевой уровень регистрирует транзакции и блоки всех соседей каждого узла и решает, отправлять ли данные на определенный узел или нет. Эта конструкция может в некоторой степени уменьшить избыточную передачу, но не является элегантной и добавляет нагрузку на хранение.
Наш путь справиться с этой проблемой - это использовать алгоритм фильтрации, чтобы фильтровать дублируемую информацию. После сравнения BloomFilter, Cuckoo Filter и многих других, мы приняли решение работать с Bloom. Мы можем добиться дублирования фильтрации миллионов пакетов данных с хранилищем только 1,7 МБ и 0,1% отрицательных результатов. Для дальнейшего сокращения избыточной передачи данных, мы установили специальную политику для блоков и крупных транзакций: их хеш будет транслироваться первым. Затем узлы могут использовать хеш для загрузки отсутствующих данных.
LAN проникновение
Мы используем UPnP Протокол для достижения LAN проникновения. UPnP отличается от других технологий, таких как UDP Hole Punching и STUN; он не требует раскрытия порта без публикации сервера. Это означает, что вы можете использовать свой домашний компьютер для доступа к нашей сети и общения с другими узлами без использования облачного сервера.
Пасхалка
В сетевом пакете P2P нашего репозитория есть каталог /example
. Мы создали приложение для обмена мгновенными сообщениями с нашим сетевым пакетом. Перейдите в каталог и запустите go build
, чтобы скомпилировать двоичный ./example
. Теперь вы можете общаться с другими пользователями в сети. Повеселитесь!