与我们交流区块链相关技术请关注长安链公众号:长安链ChainMaker,点击加入社区进群交流。
本文作者为长安链核心开发者王瑞波。
从本篇开始我们将陆续为大家分享长安链·ChainMaker 1.x版本的P2P网络核心组件——libp2p相关的内容。
libp2p简介
libp2p是由大名鼎鼎的IPFS的网络模块衍生而来,但它不需要依赖IPFS,当前已经有许多项目使用libp2p作为其网络传输层。libp2p是包含协议、规范和库文件的可用于开发P2P网络应用程序的模块化网络系统技术栈。
libp2p有多种语言实现版本:
libp2p的特性
长安链·ChainMaker底层链是用golang语言开发,所以长安链·ChainMaker 1.x的P2P网络也是用libp2p的golang语言实现go-libp2p库来做的。在我们决定使用libp2p之前,我们先了解了一些libp2p的特性,libp2p可以为我们解决如下问题:
1. Transport传输:
传输层是libp2p的基础,它负责数据从一个节点到另一个节点的可靠发送和接收。libp2p提供了一个可用于适配支持现有或未来传输协议的简单的接口,从而允许libp2p应用可以运行在不同的运行时和网络环境中。最新版本的go-libp2p已支持TCP/TLS、WebSocket、QUIC传输层实现。
2. Identity身份验证:
libp2p使用公钥作为节点身份的基础,这么做有两个互补的用途,一是根据公钥可以为节点提供一个全局唯一的身份ID(PeerId),二是所有节点可以用PeerId恢复出被认证过的节点的公钥,用于它们之间建立安全通讯。
3. Security安全性:
libp2p支持将传输层提供的一个连接“upgrading”到一个安全加密通道中。这种方式很灵活,可以支持多种通讯加密方式。当前libp2p支持TLS1.3和Noise两种(老版本支持已弃用的Secio)。
4. PeerRouting节点路由:
当你想要向另一个节点发送一个消息时,你需要知道两个信息:它的PeerId和它的网络地址。在很多情况下我们只有对方的PeerId,我们需要一种可以找到它们的网络地址的方法。节点路由是通过利用其他节点的信息发现目标节点的网络地址的过程。
在一个节点路由系统中,若我们想知道节点A的信息,我们可以向节点B请求查询,如果节点B有节点A的信息,则我们可以获得节点A的信息;如果节点B没有节点A的信息,则节点B会返回给我们一个它认为可能知道节点A的信息的节点C的信息,我们可以再向节点C请求查询。随着我们查询越来越多的节点,我们不仅增加了找到节点A信息的概率,同时我们还在自己的路由表中建立了一个更完整的网络视图,这样我们也可以为别的节点提供路由查询服务。
当前,libp2p的节点路由的稳定实现是使用分布式哈希表(distributed hash table)基于Kademlia路由算法迭代查询实现的。
5. Content Discovery 内容发现服务:
在一些系统中,我们更关心的是它能为我们提供什么,而不是我们在和谁通讯。比如,我们想要一个文件,我们可以验证这个文件的完整性,所以我们不关心从谁那拿到这个文件。
libp2p为这个场景提供了一个内容路由接口(content routing interface),它的稳定实现也是基于与节点路由中相同的KadDHT实现的。
6. Messaging / PubSub 消息传输及发布订阅:
向其他节点发送消息是大多数P2P系统的核心功能,而PubSub是一种非常有用的模式用于给一组订阅者发送消息。
libp2p定义了一个可以向已订阅指定Topic的所有节点发送消息的PubSub接口,该接口有两种实现:floodsub和gossipsub。默认使用gossipsub。
go-libp2p的实现
在了解了libp2p的特性之后,我们一起走进go-libp2p的实现。
之前我们提到过libp2p是模块化的,go-libp2p的所有模块都是一个独立的工程,模块名及描述如下表:
模块/工程 |
描述 |
go-libp2p |
总入口、装配线 |
go-libp2p-core |
核心架构、接口、基础结构、抽象定义 |
go-libp2p-blankhost |
Host接口的最小实现(在PubSub中被使用) |
go-libp2p-swarm |
内置网络状态机,管理节点间连接 |
go-ws-transport |
WebSocket传输层 |
go-tcp-transport |
TCP传输层 |
go-libp2p-quic-transport |
QUIC传输层 |
go-libp2p-circuit |
中继传输实现 |
go-libp2p-transport-upgrader |
连接升级管理 |
go-libp2p-reuseport-transport |
端口复用功能扩展 |
go-libp2p-secio |
Secio加密通道(新版已弃用) |
go-libp2p-tls |
TLS1.3加密通道 |
go-conn-security-mutistream |
安全链接多路复用 |
go-libp2p-pnet |
专有网络支持 |
go-libp2p-yamux |
yamux多路复用 |
go-libp2p-mplex |
mplex多路复用 |
go-libp2p-nat |
NAT网络穿透支持 |
go-libp2p-peerstore |
节点信息存储实现 |
go-libp2p-connmgr |
连接管理器 |
go-libp2p-record |
节点信息记录结构 |
go-libp2p-kad-dht |
KadDHT路由,依赖kbucket |
go-libp2p-kbucket |
Kad bucket结构 |
go-libp2p-pubsub-router |
PubSub节点路由适配 |
go-libp2p-consensus |
共识定义 |
go-libp2p-raft |
raft共识实现 |
go-libp2p-pubsub |
消息发布及订阅实现 |
go-libp2p-gorpc |
RPC库 |
libp2p模块间实现及依赖关系
libp2p模块间实现及依赖关系图如下:
图中黑色线代表interface实现,橘色线代表依赖关系。虚线框框代表模块分类,实线框框代表模块工程。
结语
看到这里大家libp2p应该有一个初步认知,但是也能感受到libp2p功能的强大之处。下一篇内容我们会和大家分享下libp2p的PubSub发布订阅是如何设计的,我们下一篇再见。
Tips
更多长安链开源项目QA,可登陆开源社区、技术文档库查看。
下载源码
https://git.chainmaker.org.cn/chainmaker/chainmaker-go
查阅文档
https://docs.chainmaker.org.cn/
更多社区权益申请
https://wj.qq.com/s2/8620064/7abd
“长安链ChainMaker”是国内首个自主可控区块链软硬件技术体系,由微芯研究院联合头部企业和高校共同研发,具有全自主、高性能、强隐私、广协作的突出特点。长安链面向大规模节点组网、高交易处理性能、强数据安全隐私等下一代区块链技术需求,融合区块链专用加速芯片硬件和可装配底层软件平台,为构建高性能、高可信、高安全的数字基础设施提供新的解决方案,为长安链生态联盟提供强有力的区块链技术支撑。取名“长安链”,喻意“长治久安、再创辉煌、链接世界”。