简述以太坊P2P网络之UDP

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

个人认为以太坊是区块链项目中带来技术重新认识和学习的不错的项目,特别是在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有最大报文数限制,所以能够发送的邻近节点数目是有限的,需要拆包发送

image.png

节点连接及相互通信

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

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

  • 三个通道
  • closing:关闭udp
  • gotreply:消息回复
  • addpendingpending消息处理
  • 2个 goroutine
  • udp.loop():主要监听t.gotreplyt.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
)
  • 数据包结构

image.png

  • ping-pong 时序图

image.png

总结

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


相关文章
|
4月前
|
网络协议
Qt中的网络编程(Tcp和Udp)运用详解以及简单示范案例
Tcp和Udp是我们学习网络编程中经常接触到的两个通讯协议,在Qt也被Qt封装成了自己的库供我们调用,对于需要进行网络交互的项目中无疑是很重要的,希望这篇文章可以帮助到大家。 是关于Qt中TCP和UDP的基本使用和特点:
637 7
|
24天前
|
Web App开发 缓存 网络协议
不为人知的网络编程(十八):UDP比TCP高效?还真不一定!
熟悉网络编程的(尤其搞实时音视频聊天技术的)同学们都有个约定俗成的主观论调,一提起UDP和TCP,马上想到的是UDP没有TCP可靠,但UDP肯定比TCP高效。说到UDP比TCP高效,理由是什么呢?事实真是这样吗?跟着本文咱们一探究竟!
49 10
|
1月前
|
存储 网络协议 Java
【网络】UDP回显服务器和客户端的构造,以及连接流程
【网络】UDP回显服务器和客户端的构造,以及连接流程
52 2
|
1月前
|
存储 网络协议 Java
【网络】UDP和TCP之间的差别和回显服务器
【网络】UDP和TCP之间的差别和回显服务器
65 1
|
2月前
|
监控 网络协议 网络性能优化
如何办理支持UDP协议的网络
在当今网络环境中,UDP(用户数据报协议)因传输速度快、延迟低而广泛应用于在线游戏、视频流媒体、VoIP等实时服务。本文详细介绍了办理支持UDP协议网络的方法,包括了解UDP应用场景、选择合适的ISP及网络套餐、购买支持UDP的设备并进行优化设置,以及解决常见问题的策略,帮助用户确保网络稳定性和速度满足实际需求。
|
2月前
|
网络协议
UDP协议在网络通信中的独特应用与优势
UDP(用户数据报协议)作为关键的传输层协议,在网络通信中展现出独特优势。本文探讨UDP的无连接性及低开销特性,使其在实时性要求高的场景如视频流、在线游戏中表现优异;其不保证可靠交付的特性赋予应用程序自定义传输策略的灵活性;面向报文的高效处理能力及短小的包头设计进一步提升了数据传输效率。总之,UDP适用于高速、实时性强且对可靠性要求不高的应用场景,为网络通信提供了多样化的选择。
|
3月前
|
Java
java网络编程 UDP通信协议实现局域网内文件的发送和接收
java网络编程 UDP通信协议实现局域网内文件的发送和接收
java网络编程 UDP通信协议实现局域网内文件的发送和接收
|
2月前
|
C语言
C语言 网络编程(八)并发的UDP服务端 以进程完成功能
这段代码展示了如何使用多进程处理 UDP 客户端和服务端通信。客户端通过发送登录请求与服务端建立连接,并与服务端新建的子进程进行数据交换。服务端则负责接收请求,验证登录信息,并创建子进程处理客户端的具体请求。子进程会创建一个新的套接字与客户端通信,实现数据收发功能。此方案有效利用了多进程的优势,提高了系统的并发处理能力。
|
2月前
|
C语言
C语言 网络编程(七)UDP通信创建流程
本文档详细介绍了使用 UDP 协议进行通信的过程,包括创建套接字、发送与接收消息等关键步骤。首先,通过 `socket()` 函数创建套接字,并设置相应的参数。接着,使用 `sendto()` 函数向指定地址发送数据。为了绑定地址,需要调用 `bind()` 函数。接收端则通过 `recvfrom()` 函数接收数据并获取发送方的地址信息。文档还提供了完整的代码示例,展示了如何实现 UDP 的发送端和服务端功能。
|
2月前
|
分布式计算 负载均衡 监控
p2p网络架构模型
P2P(Peer-to-Peer)模式是一种网络架构模型,在这种模型中,每个节点(peer)既是服务的提供者也是服务的消费者。这意味着每个参与的节点都可以直接与其他节点通信,并且可以相互提供资源和服务,例如文件共享、流媒体传输等。
81 6