cosmos-p2p网络架构介绍
各区块链项目中都采用了 p2p 技术
优点:适合非常多的节点互联;
名词
p2p地址本
记录了网络中被成功连接对象的地址列表
一般访问流程
场景: 节点启动顺序 A -> B -C
无声明地址的场景
- A 节点启动后网络中无其它节点, 为种子节点, 地址本为空
- B 节点启动时将目标种子节点设置为A,使用种子协议连接A
- B 节点成功连接,并将 A 节点的地址记录到地址本,广播全网(给A)
- C 节点使用种子协议连接A时,A响应一个地址本(里面只有A),并关闭连接
- C 节点从地址本中挑选最优的1个地址(只能是A)进行数据连接
注意点
- 是否是纯种子服务器模式
- 是否有声明自己的地址
- 声明地址的可访问性,内网or公网
- p2p的重试延迟机制
- p2p广播: 节点被连接时,首先响应一个地址本
cosmos
cosmos中的p2p优先级
- 连接 persistent_peers 的地址列表
- 连接 book 地址本
- 连接 seeds 种子地址
配置项
persistent_peers 持久对等体
与这些节点保持长连接, 并在连接失败时自动重拨
Seeds 节点
- 服务启动后, 主动与种子节点联系获取一份地址本
- 然后与种子节点断开连接
- 与地址本内的节点新建连接;会从地址本内选取连接质量最好的几个节点进行连接
- 并且不断地验证与地址本内其它地址的连通性, 并且从其它节点更新地址本
注意: 如果 seeds 的地址和 persistent_peers 相交, 系统将警告用户种子可能会自动关闭连接, 并且节点可能无法保持连接持久性;因为种子协议连接目标后,目标的首先动作是(响应地址本+关闭连接)
Private Peers 私人对等方 这个列表内的对等节点地址, 将不会被我加入到地址本中去,也不会传播给别的节点 可以做到私密和隐藏作用
# 验证者节点配置
pex = false
persistent_peers = '哨兵节点列表'
private_peer_ids = ''
unconditional_peer_ids = '' # 可选哨兵节点
addr_book_strict = false
# 哨兵节点配置
pex = true
persistent_peers = '' # 验证者节点,可选其他哨兵节点
private_peer_ids = '' # 验证者节点 ID
unconditional_peer_ids = '' # 验证者节点 ID,可选哨兵节点 ID
addr_book_strict = falsep2p组网模型
组网的基础原则
- 尽量互联更多的节点
- 如果存在质押比例非常大的节点, 则此节点尽量进行隔离不直接暴露
1. 单主网络模型

场景: 适合简单本地启动几个节点验证一下环境
关键配置项
# 命令行启动参数进行设定
--p2p.persistent_peers "xxxxxxxxx1@172.28.99.91:26656"
# 或者配置文件内指定 config.toml
persistent_peers = "xxxxxxxxx1@172.28.99.91:26656"2. 星型网络模型

简介
优点:配置简单,适合节点数量比较少的环境,少数节点故障不影响整体网络继续出块;
缺点:配置稍微繁琐,需要记录每个节点的nodeID, 并为每个节点单独配置 persistent_peers;在NAT环境时有些节点不能连通时,又需要单独配置。
关键配置项
即将除自身节点外的其它节点的nodeID和地址信息都配置;
实践中也可以全部节点共用一个配置,即包含自身地址时,也可以正常运行,只是日志中偶尔有报错信息, 可忽略。
# config.toml
persistent_peers = "xxxxx1@192.168.1.11:26656,xxxx2@192.168.1.12:26656,xxx3@192.168.1.13:26656"
或者命令行启动参数进行设定
--p2p.persistent_peers "xxxxx1@192.168.1.11:26656,xxxx2@192.168.1.12:26656,xxx3@192.168.1.13:26656"3. 种子网络模型

简介
大型开放互联网架构优先此模型
-
node1 作为p2p种子节点, 除声明地址外,不需要特殊配置
-
其它每个节点第一次启动时,指定种子节点为node1
-
当2个节点成功建立1次p2p连接后,p2p地址本会记录双方的地址信息,并全网共享;
-
任意节点连上一个地址本非空的节点后,都会获取到对方的地址本;
具有地址本时节点启动时的连接发起顺序
-
向p2p地址本内的节点发起连接;
-
向 persistent_peers 参数指定的持久节点发起连接;
-
如果 persistent_peers 不可用(为空或连接不上),在向种子节点请求地址本,只是请求地址本,不是实际的p2p连接;
优点:
-
配置简单,每个节点只需要指定种子节点配置和自身节点的声明地址即可;
-
种子节点的唯一用途是为 新创建的或无有效地址本的新节点 共享地址本,压力极小,故障无影响;
-
适合开放互联网上节点
缺点:
复杂的企业内网场景这种模式也比较麻烦, 因为公共节点数量可能比较少, 且因为 NAT 地址本内可能会存在很多不能有效连接的地址;
例如内网+公网组合的场景,地址本内记录内网ip时,外网节点会连接不上,记录公网ip时,部分内网节点又连接不上;
在同步中断后,进行有效p2p目标地址选择时,可能会耗费很长时间,导致当前节点长时间脱离主网;
关键配置项
[p2p]
# 程序实际监听本地网卡的地址
laddr = "tcp://0.0.0.0:26656"
# 每个节点都需要声明自身的 有效可连接地址, 此地址将被放入p2p地址本中被共享
external_address = "192.168.0.100:26656"
# 严格模式开关
# 开: 只记录节点声明的公网ip
# 关: 可以记录节点声明的内网ip
addr_book_strict = false
# 专用种子节点配置
# 即开启此配置后,节点对于p2p请求,将只响应p2p地址本, 不再同步区块数据;
seed_mode = false其它节点重点配置项
# 只需要配置种子节点的地址即可,可以配置多个目标种子
seeds = "xxxxxxx1@192.168.1.11:26656,xxxxxx2@192.168.1.12:26656"
# 也必须声明自身的p2p可连接地址
external_address = "192.168.0.101:26656"
addr_book_strict = false4. 分区网络模型

简介
-
node10作为哨兵节点,隔绝了p2p地址本的同步, 于是形成了多个网络区域
-
不同区域之间可以采用不同网络模型,如A区采用内网ip作为p2p网络,B区可以使用全p2p网络或星型等网络模型;
优点:
适合复杂网络条件下的节点组网,例如:部分节点在内网需要内网同步,部分节点在公网不同国家需要公网同步,部分节点需要避免暴露公网ip地址等场景;
缺点:
配置项稍微复杂,且需要注意避免哨兵节点单点;
关键配置项
# 哨兵节点关键配置
# 开关 p2p 的交换机, 即不会再共享自己的 p2p 地址本,做到了网络隔离
pex = false
# 外部区域节点连接此哨兵节点时,必须通过 persistent_peers 长连接才可以
persistent_peers = "xxxxxxx1@192.168.1.11:26656,xxxxxx2@192.168.1.12:26656,xxxx3@192.168.1.13:26656"