前言
《最小可行性区块链设计系列》的第五讲(http://www.jianshu.com/p/d39138a7a1ce ) 讨论了数据序列化。
本文的代码地址:(https://github.com/qikh/mini-block-chain/commit/38a9a022026a8726d22ff5a51cfa2d51646ca243) (开发语言为Kotlin,更简洁的Java)
正文
POW共识算法需要节点间通讯并最后达成共识,MiniBlockChain的网络通讯协议包括以下几个方面。
发现节点
发现节点(Discovery)的方式有几种:
1. 本地配置的节点列表
客户端的本地配置可以包含一些已知的节点列表,为了避免过多连接这些节点,通常本地配置的节点被作为备份手段,当其他发现节点的方式都失败了才使用。
2. 握手消息
节点之间建立连接后可以发送'GET_NODES'消息来获得对方的节点列表,通过这种方式可以把节点列表快速传播到区块链网络内。
3. 广播
每隔24小时,客户端会向已连接的节点广播自己的地址。
节点间的通讯
节点建立后的通讯包含以下几类消息:
- HELLO: 节点双方进行握手,交换各自的版本号、Client ID、监听端口和Node ID等信息。
- STATUS: 节点的状态信息,包括当前协议版本号,Network ID(1为主网、0为测试网),Total Difficulty等。
- NEW_TRANSACTIONS: 向区块链网络广播新的交易。
- NEW_BLOCK: 向区块链网络广播新的区块。
- GET_BLOCKS: 向对方请求区块。
- BLOCKS: 向对方发送区块。
MiniBlockChain使用Netty框架实现了异步通讯机制,使用了LengthFieldBasedFrameDecoder类来实现网络包的组包和拆包功能。
b.handler(object : ChannelInitializer<NioSocketChannel>() {
override fun initChannel(ch: NioSocketChannel) {
ch.pipeline()
.addLast(LengthFieldBasedFrameDecoder(Int.MAX_VALUE, 0, 4, 0, 4)) // 4个Byte的Length Header
.addLast(PeerClientHelloMessageHandler(node, manager)) // 对握手数据进行解码和处理
}
})
通讯协议定义完成后我们会继续完善POW同步机制,下一讲我们会讨论用户状态Account State的存储机制Patricia Tree的实现。