4 协议算法
p2p协议算法运行在每一个节点上,转发验证的交易和块。从eosio v2.x开始,节点也会转发未验证块的块id。
简化流程如下:
1、节点请求数据或者发送控制信息给对端节点;
2、如果请求被满足,对端节点执行请求,重复1
数据信息包含块或交易的内容。
控制信息使节点之间的块或交易的同步成为可能。
为了达到这样的同步,每个节点必须能够获取自己和对端节点的块和交易的状态信息。
4.1 节点/对端节点 状态
在尝试同步状态之前,每个节点需要知道它自己的块和交易的状态信息。
同时也必须能够从对端节点获取相同信息。节点必须能按需获取以下信息:
1、每个节点能够找到它自己当前有哪些块和交易
2、所有节点能找到它的对端节点有哪些块和交易
3、每个节点能找到它所请求的哪个块和交易
4、所有节点能够知道何时收到一个特定的交易
为了执行以上查询,net plugin定义特定的通信消息。这些消息被基于tcp连接的net plugin发送和接收。
4.2 协议消息
控制消息:

数据消息(即包括实际的消息内容的协议):

共7个控制信息,2个数据信息。
各个消息的具体结构不再细说。
4.3 消息处理器(从接收消息的角度看)
p2p网络使用事件驱动网络模型来处理消息,因此当收到消息后,没有轮询和循环等相关操作。
在内部,每个消息会被放到一个消息队列中,消息会根据类型被调度到合适消息处理器上。
从高层次来看,消息处理的伪代码如下:
receiver/read handler:
if handshake message:
verify that peer's network protocol is valid
if node's LIB < peer's LIB:
sync LIB with peer's; continue
if node's LIB > peer's LIB:
send LIB catchup notice message; continue
if notice message:
update list of blocks/transactions known by remote peer
if trx message:
insert into global state as unvalidated
validate transaction; drop if invalid, forward if valid
else
close the connection
4.4 发送队列(从发送消息的角度看)
协议消息被放到一个缓冲队列中,然后被发送到合适的对端节点。
从较高维度看,节点会分别对每个对端节点执行以下操作:
send/write loop:
if peer knows the LIB:
if peer does not know we have a block or transaction:
next iteration
if peer does not know about a block:
send transactions for block that peer does not know
next iteration
if peer does not know about transactions:
sends oldest transactions unknown to remote peer
next iteration
wait for new validated block, transaction, or peer signal
else:
assume peer is in catchup mode (operating on request/response)
wait for notice of sync from the read loop
5 协议改进
对p2p协议的任何软件更新必须渐进地、一致地扩展到所有节点。
这意味着,当以向后兼容的方式部署新功能时,安装更新可以减少宕机时间。
另一方面,可以通过采取最小化消息占用的措施来提高数据吞吐量,例如使用数据压缩和对协议消息进行二进制编码。
网友评论