找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

微学堂 NULS设计文档解读——网络模块

nuls 2020-3-14 10:41:39 显示全部楼层 阅读模式
网络.png
为什么要有网络模块

区块链又被叫做分布式账本系统,是基于分布式网络实现的数据系统。区块链的网络的特点是去中心化,组成网络的所有的节点都是对等的,这种网络又叫做点对点(P2P)网络。将P2P网络协议作为基础协议的区块链网络,就必须遵守P2P协议的规则,完成网络连接和数据交互。

在P2P协议中,每个加入网络的节点,既是服务器(server),可以对外提供服务,也是客户端(client),可以使用其它节点的服务。

想要实现这个目的,遵循P2P协议的网络,通常需要完成如下主要流程:

  • 节点发现:当某个节点启动后,需要从种子节点开始,寻找其它节点;
  • 节点连接:根据寻找到的节点信息,与其它节点建立连接;
  • 连接管理:维护已经建立连接的节点的连接状态信息;
  • 数据交互:建立连接之后,节点之间就可以根据协议规则,进行数据的发送和接收。

网络模块要做的正是维护一个基于P2P协议的区块链网络,所以网络模块需要实现如下主要功能:

  • 节点发现
  • 节点连接
  • 连接管理
  • 数据交互

这里需要特别说明的是:

因为NULS要构建的是一个多链并行的区块链生态网络,将支持跨链,所以在业务上,维护一条区块链内部网络会有一套业务规则,维护跨链网络会有一套业务规则。

在维护跨链网络时,业务相对复杂一些,主要分成4个部分:

  • 1、平行链将参与跨链的节点信息同步给NULS主网的节点,NULS主网会将参与跨链的节点信息同步给平行链的节点。有了参与跨链的节点信息之后,平行链和NULS主网,会将收到的跨链节点信息存储起来;
  • 2、NULS主网作为跨链平台,会维护多个跨链网络的节点信息。当NULS主网需要与平行链,进行跨链通信时,NULS主网会基于存储的跨链节点信息,与平行链进行通信;
  • 3、某个单独的平行链和NULS主网构成一个跨链网络。当平行链与NULS主网通信时,也是基于存储好的节点信息进行;
  • 4、当平行链节点和NULS主网节点收到消息时,会判断消息是发送到哪个端口的,节点通过端口来区分是跨链消息,还是本链的消息。
网络模块功能

网络模块功能体现了该模块的作用,也是开发该模块需要达到的目标。读者阅读本文档的目标是,理解网络模块具有哪些功能,以及这些功能的实现流程。

网络模块功能主要分为三类:

  • 节点管理
  • 连接管理
  • 数据交互

下面我们将详细讲解以上四类功能的作用及实现流程。

节点管理

节点管理功能主要实现:

  • 节点发现:当某个节点启动后,需要根据已有信息,寻找其它节点;
  • 节点连接:根据节点信息,在完成节点验证后,与其它节点建立连接。

节点管理功能实现的主要流程如下:

  • 1、根据本地已有信息,向其它节点发起连接请求;
    • 如果是第一次启动节点,已有信息为配置信息;
    • 如果是节点重启,已有信息为配置信息和本地已有的节点信息;
  • 2、进行节点的握手验证,根据验证结果对节点进行归类;
    • 验证通过,归类到已验证集合中,等待进行连接;
    • 验证失败,尝试多次验证,达到验证上限,依然失败,则直接移除节点信息,不再验证;
  • 3、从已验证集合中获取节点信息进行连接,连接成功将节点归类到已连接集合中;
  • 4、节点间相互同步已连接集合中的节点列表信息;
    • 当节点A主动连接上节点B时,节点A会主动发起获取节点列表信息的请求;
    • 当节点A和节点B建立连接之后,如果B节点有新增的节点信息,节点B会主动将节点信息同步给节点A;

  • 5、根据接收到的节点列表信息,重复以上4个步骤,直到节点连接数量达到上限。

在同步列表信息时,有两点需要注意:

  • 1、节点重复判断:当节点A从节点B获取到节点信息列表时,如果B给出的节点信息中,已经包含了与A节点建立了连接的节点信息,节点A便会将重复的节点信息丢弃;
  • 2、局域网节点数量限制:当同一局域网中有多个节点加入网络时,为了避免出现节点中心化的情况出现,会以该局域网的外网IP+端口号为判断条件,将该局域网的节点数量限制为最高10个。
连接管理

连接管理是对节点连接过程的细化,主要分为三个要点:

  • 握手验证
  • 连接断开
  • 连接状态管理
握手验证

握手验证分为TCP层面的验证和业务层面的验证,我们这里只说明业务层面的验证。

业务层面的验证主要根据网络通讯协议来完成。当节点A与节点B进行握手验证时,双方都会对消息中的魔法参数和协议版本进行验证,如果魔法参数和协议版本其中一个参数不一致,握手验证都会失败。

网络通讯协议中的协议版本(version)消息格式,见后面的网络通讯协议章节。

握手验证的主要流程如下:

  • 1、节点A向节点B发送包含魔法参数、协议版本的握手验证消息;
  • 2、节点B收到节点A的握手验证消息,对魔法参数、协议版本等进行验证,验证通过,节点B回传握手验证消息给节点A;
  • 3、节点A收到节点B回传的握手验证消息,对魔法参数、协议版本等进行验证,验证通过,回传握手验证响应消息verack。
  • 4、节点B接收节点A的握手验证响应消息verack,握手验证成功。

握手验证流程图:

连接断开

在握手验证过程中,会出现连接断开的情况。连接断开有TCP层面的,也有业务层面的。我们这里只针对业务层面的连接断开进行说明。

在进行握手验证时,业务层面会出现连接断开的情况如下:

  • 当节点连接数量达到上限时;
  • 当某个局域网内节点数量达到限制上限X=10时;
连接状态管理

连接成功

在握手验证通过之后,代表两个节点的连接已正式建立。之后,节点会进行如下操作:

  • 1、当节点A与节点B连接成功时,节点A和节点B,都会将对方的信息存放到已连接节点集合中;
  • 2、当需要向节点B发送消息时,节点A会从已连接节点集合中提取节点B的信息,然后向节点B发送消息。

被存入已连接节点集合的节点代表进入连接成功状态。

连接失败

在之后过程中,如果节点间出现以下情况,连接状态将由连接成功变成连接失败:

  • 1、当节点A和节点B建立连接成功时,如果节点A与节点B进行数据交互,节点B未响应,节点A会与节点B进行重连;
  • 2、当节点A重连次数达到设置的上限时,仍未连接成功,节点A会在本地将节点B的信息删除。

这代表着节点A与节点B的连接状态,由连接成功变成了连接失败。

连接断开

在NULS网络中会有多种业务,有些业务情况下,网络模块会根据具体业务要求,进行连接断开。

例如,当普通节点的连接数量达到系统设置的上限,并且仍有剩余可连接节点情况下,为了避免种子节点达到连接上限,其它节点不能连接种子节点,普通节点会随机断开与部分种子节点的连接,最后只保留与一个种子节点的连接。

完成连接断开,只需要调用连接断开的接口即可。接口详细内容请参考接口文档。

因为业务是多样的,并且未来还会增加新的业务功能,在这里对所有需要进行连接断开的业务场景,不做详细说明。

数据交互

在进行数据交互之前,所有模块需要先完成消息注册,只有注册过的消息类型,网络模块才会进行处理,否则,会直接丢弃。

消息注册是所有模块启动后,调用网络模块的消息注册接口,接口详情请参考接口文档。

节点的数据交互主要分为消息接收和消息发送两种情况。

消息接收的主要流程如下:

  • 1、节点网络模块接收到其它节点发来的网络消息;
  • 2、根据消息头中的魔法参数和cmd指令,判断消息是否已经注册,如果未注册,直接丢弃;
  • 3、如果消息合法,根据消息头中的cmd指令,网络模块将消息发送给对应的模块处理;

消息发送的主要流程如下:

  • 1、如果是广播消息,网络模块会向已连接节点集合中的所有节点发送消息;
  • 2、如果是发送给指定节点的消息,网络模块会从已连接节点集合中,获取对应节点的信息,然后进行发送。
其它网络通讯协议version

用于建立连接(握手)

LengthFieldsTypeRemark
4versionuint32节点使用的协议版本标识
20addr_youbyte[20]对方网络地址【IP+PORT1+PORT2】PORT2为跨链server端口 如:[10.32.12.25 8003 9003] 16byte+2byte+2byte
20addr_mebyte[20]本节点网络地址【IP+PORT1+PORT2】PORT2为跨链server端口 如:[20.32.12.25 7003 6003] 16byte+2byte+2byte
4block_heightuint32节点高度
block_hashvarByte区块hash
??extendVarByte扩展字段,不超过10个字节
verack

用于应答version

LengthFieldsTypeRemark
1ack_codeuint8返回码,1代表正常
ping

在某条链自己的网络中,因为每隔10s会出块,所以网络中不会存在长时间无消息的收发情况。 但是在主网与平行链连接的跨链网络中,就没有10s出块的区块消息交互,所以需要ping、pong 来维护连接。

LengthFieldsTypeRemark
4randomCodeuint32随机数
pong

用于回应ping

LengthFieldsTypeRemark
4randomCodeuint32随机数
getaddr

用于请求网络中可用节点的连接信息。

LengthFieldsTypeRemark
2chainIduint16链id
1isCrossAddressuint8是否请求跨链地址
addr

用于应答getaddr,或向网络中宣告自身的存在,节点接收到该消息后,判断节点是否已知,如果是未知节点,则保存,待验证通过后向网络中传播该地址。

LengthFieldsTypeRemark
??addr_listnetwork address每个节点18字节(16字节IP+2字节port)
getTime

由于节点启动后,会有一个本地时间,但是整个网络会有一个统一的网络时间,整个网络的运行都依照网络时间在进行,这里就是向其它节点获取已有的网络时间,便于本地节点进行网络时间的校正。

LengthFieldsTypeRemark
4messageIduint32请求id
responseTime

回复getTime请求,回传网络时间

LengthFieldsTypeRemark
4messageIduint32请求id
4timeuint32时间值
模块配置"port": 18001,"chainId": 2,"maxInCount": 300,"maxOutCount": 20,"packetMagic": 3136151,"selfSeedIps": "192.168.1.57:8888","crossPort": 18002,"crossMaxInCount": 300,"crossMaxOutCount": 10,"moonSeedIps": "192.168.1.192:8088","timeServers":"sgp.ntp.org.cn,cn.ntp.org.cn,time1.apple.com,ntp3.aliyun.com,ntp5.aliyun.com,us.ntp.org.cn,kr.ntp.org.cn,de.ntp.org.cn,jp.ntp.org.cn,ntp7.aliyun.com"网络模块启动时需要依赖的模块

网络模块在启动时,需要依赖以下模块:

1、区块管理模块:因为节点启动时,网络模块需要调用区块管理模块接口,获取最新区块高度和Hash值,区块高度和Hash值,将在进行握手验证时,发送给目标节点。

2、协议升级模块:网络模块动态依赖协议升级模块。动态依赖的意思是:如果有协议升级模块,就依赖,没有协议升级模块,就不依赖。


项目网站:https://nuls.io
个人微信:nulsio,加入NULS社群
官方QQ群:474789123
您需要登录后才可以回帖 登录 | 立即注册

  • 4 关注
  • 3 粉丝
  • 519 帖子