P2P网络#
P2P(peer-to-peer)架构的特点在于:其网络中的个体在地位和功能上是平等的,它们都能同时既消耗资源又提供资源。
通信协议#
从TCP/IP协议族分层的角度来说,P2P网络中实际的数据交换,依然是网络层用IP协议,传输层用TCP协议。
此处所说的协议应算作应用层协议。即以太坊结点(node)之间通信应该遵循的通信协议。
所谓协议,其实就是通信所支持的数据交换类型。
目前以太坊主要遵循以下消息类型(eth/62, eth/63)
1 | eth/62 协议: |
同步模式#
Fast模式: 同步区块头,区块体,以及状态数据
Full模式:同步区块头,区块体,并通过重放交易生成收据和状态数据
Light模式: 只同步区块头,其他数据需要时通过网络请求获取
同步建立#
握手:发送己方状态给远端,远端读取状态,通过对比创世块,网络ID,协议版本,一致方可继续通信。
同步业务#
广播新出现的交易
txBroadcastLoop()会在txCh通道的收端持续等待,一旦接收到有关新交易的事件,会立即调用BroadcastTx()函数广播给那些尚无该交易对象的相邻个体。广播新挖出的区块
minedBroadcastLoop()持续等待本个体的新挖出区块事件,然后立即广播给需要的相邻个体。
当不再订阅新挖出区块事件时,这个函数才会结束等待并返回。
在收到新挖出区块事件后,minedBroadcastLoop()会连续调用两次BroadcastBlock()。
两次调用仅仅一个bool型参数propagate
不一样,
当该参数为true时,会将整个新区块依次发给相邻区块中的一小部分;
而当其为false时,仅仅将新区块的Hash值和Number发送给所有相邻列表。定时与相邻个体进行区块全链的强制同步
syncer()首先启动fetcher,然后进入一个无限循环。
每次循环中都会向“最优”的peer作一次区块全链同步。
所谓”最优”指的是peer中所维护区块链的TotalDifficulty(td)最高。
同步发起分两种情况:- 如果有新peer到达,则在peer列表数目大于5时,发起同步;
- 如果没有新peer到达,则以10s为间隔定时发起同步。
将pending交易同步给新加入的peer
txsyncLoop()主体也是一个无限循环。
每当有新peer加入时,向其广播所有的pending交易。
为了减缓带宽压力,将要广播的交易拆分成小的数据包(<=100k
)进行发送。
同步逻辑#
只有在远端拥有更大的整体难度(td)时才从此远端同步。通过downloader.synchronise()完成。
首先,获取远端最新区块头信息;
然后,找出共同的祖先从而确定同步范围;
最后,调用spawnSync()并发完成一组数据(块头,块体,收据,状态)的获取和存储。