解读区块链中P2P网络结构工作机制

解读区块链中P2P网络结构

区块链节点内部根据不同的功能划分了不同的业务模块,其中网络模块主要负责节点之间的点对点(P2P)的通信,具有管理节点、节点间的数据收发等功能。网络模块既是服务的请求者也是服务提供者。作为服务提供者,每个节点的网络模块都配置有服务端口,网络模块会在此服务端口上监听来自其他节点的通信请求。

1、区块链世界中的其他节点如何加入到现有P2P网络中

在区块链的全网节点中存在一类叫“种子节点”的节点(以下简称种子节点),该类节点是网络中的最早出现的节点,负责对其他节点的分享工作。
在这里插入图片描述

在区块链的安装程序中会初始化配置种子节点的信息,包括节点的IP地址和端口号,所有新加入的节点在安装区块链程序并启动时会与初始化的种子节点建立连接,将自身的IP地址和端口号告知种子节点,种子节点也将现有P2P网络中的其他节点信息告知新节点,并将新加入的节点告知其他节点。

新节点收到其他节点信息后,与这些现有节点建立连接。自此,新加入的节点就加入到P2P网络中。

2、网络模块如何与种子节点沟通的?

在这里插入图片描述
新节点与初始化的种子节点建立连接,向种子节点喊话:“咱们俩的通信信息(IP地址和端口)分别是XXX,我要与你建立连接。”

种子节点:“你先等等,我先检查下是否符合我的连接标准”。种子节点的连接标准是:1)跟我(种子节点)建立连接的数量是否达到了我能承受的最大值;2)你(新节点)之前是否与我(种子节点)已经建立了连接;3)你跟我之间的连接数量是否达到了允许的最大值。

当新节点不符合种子节点的接入标准时,新节点立即断开与种子节点的连接,但是新节点是不会放弃的,将这个种子节点标记为不可用节点,会有其他工作人员来定时检查此种子节点的可用性的。

当新节点符合种子节点的接入标准,种子节点也会主动的将自己和新节点的通信信息反馈给新节点,以示同意新节点的连接。新节点收到种子节点的反馈后,首先记录与种子节点建立连接的时间;其次新节点再次回复种子节点,以示我确认要与你建立连接;最后主动向种子节点请求P2P网络中其他节点的信息。

种子节点在收到新节点确认建立连接的回复消息或者获取网络其他节点的请求消息时,种子节点将记录的其他有效节点信息反馈给新节点,种子节点认为的“有效节点”是指其他种子节点信息和收到的其他节点分享的自身节点信息。

新节点收到种子节点反馈的其他节点信息后,并不会直接使用,而是记录下来并标记为“待检查”,由其他线程来检查这些节点的可用性。

3、新节点的网络模块如何与其他兄弟节点沟通呢?

上面讲述了如何与种子节点建立连接并获取当前P2P网络的其他兄弟节点,接下来讲述如何与兄弟节点建立连接。沟通流程如下:

在这里插入图片描述

在与种子节点建立连接后,从种子节点获取到了其他兄弟节点的通信信息,但是处于“待检查”状态,当其他人对这些节点检查通过后,就标记为“可连接”状态。

网络模块要定期(例如每隔5秒钟)对“可连接”或“已连接”的节点进行检查。分别进行不同的检查:

1)对于已经建立连接的节点个数进行检查,发现已经连接的节点数超过了,为了降低种子节点的负载,仅保留与其中任一个种子节点的连接,断开与其他种子节点的连接。

2)对于“可连接”的节点,新节点与它们建立连接,向其他“可连接”的兄弟节点发送握手消息:“咱们俩的通信信息(IP地址和端口)分别是XXX,我要与你建立联系。”

兄弟节点:“你先等等,我先检查下现在是否符合我的连接标准”,我的接入标准跟种子节点的是一样。当新节点不符合兄弟节点的接入标准时,新节点立即断开与兄弟节点的连接,但是新节点是不会放弃的,将这个兄弟节点标记为“不可用”节点,会有其他线程来定时检查此兄弟节点的可用性的。

当新节点符合兄弟节点的接入标准,兄弟节点也会主动的将自己和新节点的通信信息反馈给新节点,以示同意新节点的连接。新节点收到兄弟节点的反馈后,首先记录与兄弟节点建立连接的时间;其次新节点再次回复兄弟节点,以示我确认要与你建立连接。

兄弟节点收到新节点确认建立连接的回复消息时,将记录的其他有效节点信息反馈给新节点,兄弟节节点认为的“有效节点”是指其他种子节点信息和收到的其他节点分享的自身节点信息。

4、新节点网络模块的登记工作

网络模块要定期(例如每隔5秒钟)对收到P2P网络中的其他节点信息做好保存登记工作,要把这些节点信息保存下来,以免丢失。将这些信息写入数据库中。例如采用Nosql数据库RocksDB。

5、网络模块对非可用节点的巡检工作

为了保证及时发现复活的节点(即由非可用节点状态转变为可用节点),网络模块定期(每隔10秒)要对“非可用”节点进行巡检,非可用节点包括断开连接的节点、待检查的节点和连接失败的节点,从中发现可连接的节点。

网络模块尝试与所有非可用节点建立连接,如果发现非可用节点能正常建立连接,则将节点标记为“可连接”状态,由其他线程负责与“可连接”状态的节点进行沟通,并且将发现的“可连接”节点向已发现的P2P网络的其他节点进行广播,告知其他节点“此节点已经变为可连接状态”。如果未连接成功则等待下一轮的巡检此节点。

6、全网时间同步工作

区块链的业务与时间戳密不可分,因此必须保证各个节点的时间是同步的,通过计算本地时间与网络时间的时间偏差(以下称为网络时间偏移量),利用该网络时间偏移量对每个节点的本地时间进行修正来保证全网时间的一致性。在参与区块链的业务时,本地节点的时间计算方式为本地系统时间加上网络时间偏移量即得到当前节点系统时间。

每个节点从公共的NTP服务器获取格林威治标准时间(代号GMT时间),计算本地时间与GMT时间的网络时间偏移量,利用该时间偏移量参数调整本地节点的时间,并且每隔2分钟就重新计算时间偏移量;如果计算时间偏移量的时间消耗较大(大于3秒)时要立即重新计算。

网络时间偏移量的计算方法如下:每个节点从至少三个公共的NTP服务器获取网络时间,然后分别减去本地时间得到网络时间偏移量参数,为了防止网络震动导致个别网络时间的偏差较大而影响最终时间偏移量的计算,要排除掉偏移量中相互之间偏差较大的偏移量参数(如大于500ms),最后取这些偏移量参数的算术平均值,即为本地节点网络时间偏移量。

如果从公共的NTP服务器无法获取到网络时间,则向全网其他节点获取时间偏移量,然后取获取到的时间偏移量参数的算术平均值,即为本地节点网络时间偏移量。

7、节点间消息转发

为了提高处理能力,与节点之间的交互可以采取异步消息的方式,当与其他节点进行异步消息交互时,将消息放入消息转发队列中,在后台完成将消息转发给其他目的节点的消息转发工作。

不断地监听每个节点的消息转发队列,查看是否有待发送的消息,如果存在则将待发送的消息发送给该节点。为了防止因节点待转发的消息过多而引起其他节点的消息堵塞,限制每个节点每轮最多只转发10条消息,发完后等待下一轮。

8、节点内部模块之间消息转发

区块链节点中分为网络模块、账本模块、账户模块、区块模块、交易模块、合约模块等11个模块,各个模块都各司其职,负责处理各类消息。当网络模块收到其他节点发送过来的消息后,根据消息名称转交其他不同的模块进行处理。模块划分如下所示:

在这里插入图片描述

网络模块只负责处理网络通信协议部分的消息,包括版本消息、确认消息、地址消息、获取地址消息、获取时间消息、响应时间消息、心跳消息等与网络相关的消息名称,当网络模块收到这些消息名称的消息之后,由该模块的相应处理器进行业务处理。

当网络模块收到其他消息后,首先根据消息名称查找能处理该消息的模块名称,然后将此消息封装成内部命名的消息格式,再通过websocket通信方式转发给处理模块;但是如果与该模块之间的通道被占满,则就将该消息放入消息转发列表中,由网络模块在后台进行消息转发,接收模块在接收到此消息后由消息处理器进行处理。

本文转载 光谷区块链技术

发布了38 篇原创文章 · 获赞 11 · 访问量 3843

猜你喜欢

转载自blog.csdn.net/qq_43721475/article/details/104662564