简述以太坊P2P网络之UDP_区块链

个人认为以太坊是区块链项目中带来技术重新认识和学习的不错的项目,特别是在P2P网络这一块。本文将介绍P2P网络中负责节点之间的通信连接和服务发现,本文的内容主要是对代码层级的理解,可能存在对其理解的错误,欢迎指点。包括以下两个方面:

  • 种子节点初始化,节点发现
  • 节点连接及相互通信

​pending​​一种延迟处理逻辑,提供一个回调机制

  • 当某一个操作发起异步请求时,就使用​​pending​​结构封装一个闭包,当收到异步回复后从pending列表取出这个闭包,执行回调,因此在这个回调里可以完成数据包校验等后处理,如findnode操作将更新k桶的操作暂存,再获取到异步回复后执行这个闭包完成k桶更新
  • 提供多个回复接收功能,一个RPC请求可能会对应多个回复包,比如findnode对应多个neigbours回复包,此时可以提供多个​​pending​​进行逐个包校验

种子节点初始化及节点发现

这部分的逻辑的实现主要在​​p2p/discover/table.go​​​中,在udp中​​newUDP​​​方法调用​​newTable​​开始种子节点及节点的发现。

  • ​newTable​​​:执行该函数会传入​​Bootnodes​​​信息,配置信息在​​params/bootnodes.go​​中,为初始连接节点,服务启动后就从这些节点开始进行节点的发现和扩散。关键执行方法
    • ​tab.setFallbackNodes​​​:验证​​bootnodes​​​信息,将节点信息赋值给​​tab.nursery​
    • ​tab.seedRand​​​:设置随机​​seed​
    • ​tab.loadSeedNodes​​​:将​​bootnodes​​加入路由表
    • ​tab.loop​​​:创建​​goroutine​​发现节点并进行连接
      • ​tab.doRefresh​​​:创建​​goroutine​​刷新所有节点(30分钟),并进行连接
      • ​tab.lookup​​:查找距离自己最近的节点
        • ​tab.closest​​​:获取距离​​target​​​最近的​​16​​个节点
        • ​tab.findnode​​​:向最近的节点发起​​findnode​​​请求,并增加处理​​neighborsPacket​​​闭包的​​pending​​​,具体实现为​​udp.go​​​中的​​findnode​​​,对于超过24小时没有接收到​​ping​​​包的节点重新发送​​ping​​​;对端节点接收到​​findnode​​​请求后,查找附近的16个节点,并发送​​neighborsPacket​

--

  • ​findnode-neighbors​​ 时序图

由于UDP有最大报文数限制,所以能够发送的邻近节点数目是有限的,需要拆包发送

简述以太坊P2P网络之UDP_区块链_02

节点连接及相互通信

P2P服务的启动位于​​p2p/server.go​​​ 中的​​Start()​​。

建立一个UDP连接服务​​discover.ListenUDP​​​这个方法的关键实现是初始化三个通道,2个​​goroutine​​ 。

  • 三个通道
    • ​closing​​:关闭udp
    • ​gotreply​​:消息回复
    • ​addpending​​​:​​pending​​消息处理
  • 2个 ​​goroutine​
    • ​udp.loop()​​​:主要监听​​t.gotreply​​​和​​t.addpending​
      • ​t.addpending​​:接收并增加一个闭包
      • ​t.gotreply​​​:接收回复遍历,执行​​callback​​​通知​​errC​​通道
    • ​udp.readLoop()​​​:读取UDP数据包,执行​​t.handlePacket​​进行数据包处理
      • ​t.handlePacket​​​:执行​​decodePacket​​​对数据包进行解码,然后调用相应数据包的​​handle​​方法
网络传输四种数据包
  • 数据包类型
const (
pingPacket = iota + 1 // zero is 'reserved'
pongPacket
findnodePacket
neighborsPacket
)
  • 数据包结构

简述以太坊P2P网络之UDP_时序图_03

  • ping-pong 时序图

简述以太坊P2P网络之UDP_区块链_04

总结

区块链技术是一个不错的技术,以太坊让我们重新理解了网络的应用。本文简单介绍了P2P网络的UDP协议这一块,实际上网络及节点的发现是有一整套算法,经典的有 Kademlia 网络,这里不做介绍。