# Host、Peer与Node
host即主机,是p2p网络的参与对象,由于既处理请求和发送请求,所以一个host既是服务器也是客户端。host概念容易与peer概念混淆,其type是一个interface,包括一系列需要实现的方法,其中ID()方法返回的对象类型为peer.ID(在peer.go)中定义。
我们在启动一个节点的时候,必然要创建一个host:host是节点Node结构的一个变量。
peer对应于ID,其由创建host时的键值对的publickey生成而来,因此,我们可以根据peer.ID与host.ID()比较,判断本地主机与对等端是否是同一个主机。
加入网络后的host与peer是相对的,每一个peer都是host,每一个host都是peer。站在某个node的角度,该node即为host,其它node即为peer。我们可以通过PubSub服务的ListPeers,来获取全网的[]peer.ID。
可以理解,host或peer由ID唯一标识,ID在host创建时候根据同时创建的公钥生成。
node即节点,更准确的称呼为网络节点,我们在实现的时候,直接以network结构体来定义它,其结构包括host在内的多个变量,区块链运行从启动一个一个节点开始。
host是一个类型对象(type object),实现了作为一个既是服务器也是客户端的节点的P2P网络所需的处理方法和参数配置,node是一个结构体(struct),peer等同于ID。
每个peer在加入P2P网络之前也是一个host,host在创建完毕加入网络后成为一个peer。
网络中的每一个peer的功能可能不同(由加入网络之前创建host确定),host自身知道自己具备什么功能,虽然可以随时获取全网的peer,但并不知道其它peer所具备的功能及内容,也就是一个host只知道一个peer的ID,除此之外,一概不知,这也体现了P2P网络的匿名特性。一个host想要什么,通过通信通道向全网发出命令消息,或者在成功连接到一个peer后,发送命令消息给对方,由该peer给出响应,才能管窥一个peer的部分功能和内容。
我们实际进行编程交互的时候,是以node为对象进行处理的,一切从节点的startnode方法开始(返回一个node对象:*Network):
```
func StartNode(chain *blockchain.Blockchain, listenPort, minerAddress string, miner, fullNode bool, callback func(*Network))
```
# Channel 通信通道
Channel结构体包含一个chan的通道Content(遵循先进先出的规则)。
```
type Channel struct {
ctx context.Context
pub *pubsub.PubSub//发布
topic *pubsub.Topic
sub *pubsub.Subscription//订阅
channelName string
self peer.ID
Content chan *ChannelContent//有缓冲的非阻塞通道,通道大小ChannelBufSize=128
}
```
在创建host过程中,创建所有的通信通道,并将其加入到pubsub服务中(在join中启动无限循环,读取订阅的消息),当读到订阅的消息后,将消息体写入到自身的通道队列中。
在启动一个node的最后:
ui.Run(network)
在Run中,开启一个协程:
go ui.handleEvents(net)
在handleEvents中,使用一个无限循环,读取通道的队列消息进行处理:
```
case m := <-ui.GeneralChannel.Content:
ui.HandleStream(net, m)
casem := <-ui.MiningChannel.Content:
ui.HandleStream(net, m)
casem := <-ui.FullNodesChannel.Content:
ui.HandleStream(net, m)
```
# pubsub 订阅发布服务系统
pubsub服务是P2P网络节点之间交互的关键。基于发布/订阅的模式,将消息的发送和处理分离,使得对等网络节点间的交互成为可能。
任何一个主机(节点或对端),同时都是一个订阅发布服务系统。但一个主机可能同时具备订阅和发布的功能,也可能只有发布的功能而没有订阅的功能,这在创建主机时候确定。
libp2p的pubsub是一个基于Gossip协议的消息路由器。
Gossip 过程是由种子节点发起,当一个种子节点有状态需要更新到网络中的其他节点时,它会随机的选择周围几个节点散播消息,收到消息的节点也会重复该过程,直至最终网络中所有的节点都收到了消息。这个过程可能需要一定的时间,由于不能保证某个时刻所有节点都收到消息,但是理论上最终所有节点都会收到消息,因此它是一个最终一致性协议。
Gossip protocol 也叫 Epidemic Protocol (流行病协议),实际上它还有很多别名,比如:“流言算法”、“疫情传播算法”等。基于六度分隔理论,任何信息的传播其实非常迅速,而且网络交互次数不会很多。比如Facebook在2016年2月4号做了一个实验:研究了当时已注册的15.9亿使用者资料,发现这个神奇数字的“网络直径”是4.57,翻成白话文意味着每个人与其他人间隔为4.57人。
**Gossip 中的通信模式**
在 Gossip 协议下,网络中两个节点之间有三种通信方式:
* Push: 节点 A 将数据 (key,value,version) 及对应的版本号推送给 B 节点,B 节点更新 A 中比自己新的数据
* Pull:A 仅将数据 key, version 推送给 B,B 将本地比 A 新的数据(Key, value, version)推送给 A,A 更新本地
* Push/Pull:与 Pull 类似,只是多了一步,A 再将本地比 B 新的数据推送给 B,B 则更新本地
如果把两个节点数据同步一次定义为一个周期,则在一个周期内,Push 需通信 1 次,Pull 需 2 次,Push/Pull 则需 3 次。虽然消息数增加了,但从效果上来讲,Push/Pull 最好,理论上一个周期内可以使两个节点完全一致。直观上,Push/Pull 的收敛速度也是最快的。
**Gossip 安全增强**
对于大型区块链用户来说,重点是稳定性、可扩展性和安全加固。
为此,Gossipsub 协议设计并实现了新版本 v1.1 ([https://blog.ipfs.io/2020-05-20-gossipsub-v1.1/](https://blog.ipfs.io/2020-05-20-gossipsub-v1.1/))。这个新的 P2P PubSub 路由器包含了几个安全扩展,增加了对 Sybil、eclipse 和垃圾邮件攻击的保护。
这项工作极为重要,因为大型区块链的采用者(如 Filecoin 和 Ethereum 2.0)需要一个安全的消息层来分发他们的时间敏感和有价值的数据,而不容易受到恶意行为者的攻击。
- 重要更新说明
- linechain发布
- linechain新版设计
- 引言一
- 引言二
- 引言三
- vs-code设置及开发环境设置
- BoltDB数据库应用
- 关于Go语言、VS-code的一些Tips
- 区块链的架构
- 网络通信与区块链
- 单元测试
- 比特币脚本语言
- 关于区块链的一些概念
- 区块链组件
- 区块链第一版:基本原型
- 区块链第二版:增加工作量证明
- 区块链第三版:持久化
- 区块链第四版:交易
- 区块链第五版:实现钱包
- 区块链第六版:实现UTXO集
- 区块链第七版:网络
- 阶段小结
- 区块链第八版:P2P
- P2P网络架构
- 区块链网络层
- P2P区块链最简体验
- libp2p建立P2P网络的关键概念
- 区块链结构层设计与实现
- 用户交互层设计与实现
- 网络层设计与实现
- 建立节点发现机制
- 向区块链网络请求区块信息
- 向区块链网络发布消息
- 运行区块链
- LineChain
- 系统运行流程
- Multihash
- 区块链网络的节点发现机制深入探讨
- DHT
- Bootstrap
- 连接到所有引导节点
- Advertise
- 搜索其它peers
- 连接到搜到的其它peers
- 区块链网络的消息订发布-订阅机制深入探讨
- LineChain:适用于智能合约编程的脚本语言支持
- LineChain:解决分叉问题
- LineChain:多重签名
- libp2p升级到v0.22版本
- 以太坊基础
- 重温以太坊的树结构
- 世界状态树
- (智能合约)账户存储树
- 交易树
- 交易收据树
- 小结
- 以太坊的存储结构
- 以太坊状态数据库
- MPT
- 以太坊POW共识算法
- 智能合约存储
- Polygon Edge
- block结构
- transaction数据结构
- 数据结构小结
- 关于本区块链的一些说明
- UML工具-PlantUML
- libp2p介绍
- JSON-RPC
- docker制作:启动多个应用系统
- Dockerfile
- docker-entrypoint.sh
- supervisord.conf
- docker run
- nginx.conf
- docker基础操作整理
- jupyter计算交互环境
- git技巧一
- git技巧二
- 使用github项目的最佳实践
- windows下package管理工具