更通用的P2P网络协议栈——Libp2p

2020-08-13 10:09 栏目:经验之谈 来源:网络整理 查看()

什么是Libp2p?

Libp2p是一个用于构建p2p网络的模块化网络栈和库,它起源于IPFS开源项目。模块化设计使得为各种分散应用构建P2P网络层成为可能。目前,著名的区块链项目以太网2.0、Pokdot和BitXHub都选择基于Libp2p库构建系统网络层。Libp2p作为一种p2p网络协议栈,是通过解决实际问题而成长起来的,可以看作是构建P2P网络的经验积累。

Libp2p解决了什么问题?

作为一种网络协议栈,Libp2p主要解决两个问题:

节点发现

节点发现用于发现P2P网络中的其他节点,维护节点的在线状态,根据节点状态调整网络连接,构建稳定的网络拓扑。

数据传输

数据传输负责节点之间的数据流。为了支持异构网络设备的互连,Libp2p的核心要求之一是传输层是不可知的。Libp2p支持不同的传输层协议,如TCP、UDP、QUIC等。在传输层建立连接后,需要考虑网络数据的隐私性。Libp2p对传输通道进行加密,节点通过加密的通道进行通信。为了高效地传输数据,Libp2p支持多路复用连接,以支持节点之间的多个并发流通信。

本文主要讨论Libp2p来解决数据传输问题。该代码基于go-libp2p v0.9.2.

Libp2p如何解决数据传输问题?

传输层不可知

传输层不可知论意味着Libp2p支持多种传输层协议,如TCP、UDP、QUIC等。当使用Libp2p库时,应用开发者不需要知道用来完成数据传输的传输层协议,Libp2p会根据远程节点的地址信息自动完成协议选择。

地址定义

数据传输基于节点连接。在拨号到远程节点并建立连接之前,您需要知道远程节点的监听地址。由于每种传输协议都有自己的地址格式,Libp2p使用一种称为“多地址”的编码方案来统一不同协议的地址格式。

TCP/IP传输协议“多地址”描述如下:

/ip4/127.0.0.1/tcp/9999

UDP传输协议“多地址”描述如下:

/ip4/127.0.0.1/udp/9998

使用这个描述代替127.0.0.133609999有什么好处?“多地址”可以更清楚地描述所使用的协议,例如,127.0.0.1属于IPv4协议,9999属于TCP协议,9998属于UDP协议。

以上是“多地址”描述的节点侦听地址。拨打节点时,也使用“多地址”,但需要添加远程节点的标识,例如:

/ip4/192 . 168 . 100 . 100/TCP/9999/P2P/qmceprate 8 shncph8 wjkrezt5cpxf2rwhyxybaldcl c1iv 6

这样,我们就知道对方使用的是IP4,地址:192.168.100.100,TCP协议,端口9999,它是一个P2P节点,节点id为:qmceprat 8 shncph8 wjkrezt5cpxf2rwhybaldcl 1 V6。

节点标识定义

节点标识是一个字符串,由节点公钥哈希生成,并由base58编码。节点标识在整个网络中是唯一的,拨号时使用节点标识可以有效解决中间人攻击问题。

支持多种传输协议

Libp2p的Swarm模块负责将多个传输层组合成一个接口,从而允许应用程序在不指定要使用的传输层的情况下拨打节点。它还负责协议协商、多路复用、建立安全通信和其他接口升级操作。

更通用的P2P网络协议栈——Libp2p

网络接口是图书馆p2p的外部服务接口,而群是网络接口的具体实现。Libp2p维护群中现有连接和支持的传输层协议的状态。Swarm通过以下方式支持多传输协议:

为了支持多种传输层协议,当创建一个新节点时,该节点支持的传输层协议将通过添加传输被添加到Swarm的传输结构中。

当节点开启监听时,群模块将调用传输层监听获取监听地址对应的传输层协议,并调用相应传输层协议的监听功能。

当一个节点主动拨打其他节点时,群模块将调用传输层协议来获取用于拨打地址的传输协议,并调用相应传输层协议的拨号功能。

更通用的P2P网络协议栈——Libp2p

Libp2p通过“多地址”编码方案统一了不同协议的地址格式,并在Swarm模块中根据“多地址”解析协议,调用相应协议的接口完成具体操作,从而达到应用层不需要关注所使用的传输层协议的目的。

数据的安全传输

上述过程建立了节点之间的连接。Libp2p如何保证传输数据的隐私?这里,以TCP协议为例进行介绍。

更通用的P2P网络协议栈——Libp2p

传输控制协议是传输控制协议的传输层实现模块,它结合了升级模块。升级者负责将原始的TCP连接升级到支持加密和多路复用的连接。Secio和tls是实现SecureTransport接口的两个库,Libp2p库默认使用secio加密库。

更通用的P2P网络协议栈——Libp2p

以上是TCP从远程节点接收连接请求的调用过程,主动拨号远程节点的调用过程类似。secio包的runHandshakeSync函数在这里用于加密连接。

Secio库密钥交换使用Diffie-Hellman密钥协商算法(secio协议的具体内容)。当然,tls也可以用来加密连接。

多流复用

Libp2p应用通常在节点之间开放许多独立的通信流,并且可能与远程节点同时开放多个并发流。多路复用允许通过与远程节点建立连接来完成整个生命周期中的数据传输和接收。类似地,只需要处理一个NAT操作,因为具有相同远程节点的所有流共享相同的底层传输连接。当Libp2p被配置时,流多路复用模块被启用,并且Swarm将在拨号远程节点和监听连接时使用它们。如果远程节点支持相同的多路复用实现,Swarm将在建立连接时选择并使用它;如果您拨打Swarm与之建立连接的远程节点,新创建的流将自动在现有连接上多路复用。

更通用的P2P网络协议栈——Libp2p

升级者的多路复用器模块负责将加密连接升级到支持多路复用的连接。MuxedConn是复用操作接口,multiply是复用操作的具体实现,负责具体的流创建和管理。除了默认的多路复用,Libp2p还支持不同的多路复用器实现,如yamux、spdy和muxado。

更通用的P2P网络协议栈——Libp2p

以倾听为例。收到连接请求后,升级者的安全模块将首先将连接升级为加密连接。然后,通过新多路复用创建一个多路复用器实例,将接口升级到支持流多路复用的接口。

MuxedConn的OpenStream接口用于向远程节点发送新的流请求,而AcceptStream接口用于从远程节点接收流创建请求。

因为节点之间的多个通信流仍然使用相同的连接,所以为了区分不同的流,复用模块实际上向发送的数据添加了报头字段。

更通用的P2P网络协议栈——Libp2p

头61位是流id,每次创建新流时,流id都会增加。

报头的低3位表示消息类型,总共定义了四种流消息:

新闻流标签=0 //创建流消息

MessageTag=2 //数据消息

关闭标记=4 //关闭消息流

重置=6 //重置流消息

Libp2p通过升级器的多路复用器模块将公共接口升级为支持流复用的接口。当节点之间发生数据传输时,并行数据通过流而不是新连接来发送和接收,从而减少了节点之间新连接的消耗。为了区分不同流上的信息,流多路复用器向发送和接收数据添加表示流信息的报头字段。

摘要

从Libp2p解决的数据传输问题可以看出,Libp2p由许多小组件组成,它们遵循相同的接口,可以根据使用场景进行替换,每个组件库都可以独立开发和升级,而不影响其他部分。“多地址”的地址编码方案使得基于Libp2p的应用层开发不必关注底层使用的传输层协议。节点可以通过协议协商选择彼此支持的加密模块对数据传输通道进行加密,从而保证数据隐私。

微信二维码
售前客服二维码

文章均源于网络收集编辑侵删

提示:仅接受技术开发咨询!

郑重申明:资讯文章为网络收集整理,官方公告以外的资讯内容与本站无关!
NFT开发,NFT交易所开发,DAPP开发 Keywords: NFT开发 NFT交易所开发 DAPP开发