C26cadcf2a5d94c1a2204abc2e61fc4e
Go Ethereum P2P : 实现[1]

简介

P2P 部分的代码实现。
P2P 在 Go-ethererum 项目中是非常重要的一个组件。 所有的重要的服务都构建在其上(eth/whisper/swarm)。P2P 主要负责本地节点与其它节点的所有通信功能, 包括:

  1. 发现其它的Ethereum 节点。
  2. 管理/接收其它节点发起的连接。
  3. 主动向其它的ethereum 节点发起连接。
  4. 接收上层协议的请求或者转发接收数据给上层协议

只有在通信信道通畅以后, 构筑在其上的以太坊核心算法/协议才能正常的工作。所以说虽然这部分代码功能本身和区块链相关的逻辑与算法并不是紧耦合,但是它的稳定性/可靠性/性能 却关乎到整个节点的表现。

更上层的服务例如eth 的核心逻辑都会涉及到P2P模块, 所以我们在正式开始eth模块分析之前, 先需要完成P2P 模块分析。

代码目录结构

src_root/p2p/的目录结构
├── dial.go 主要负责主动发现节点,连接节点,查找节点地址信息 。
├── discover 目前正在使用的老版本的Kademlia 协议实现
│ ├── node.go 网络中的主机节点数据结构
│ ├── ntp.go 网络时间服务的包装,主要用于时钟同步
│ ├── table.go 核心的节点路由表实现。Kademlia 的核心设计
│ ├── udp.go Kadmelia的UDP协议实现
├── discv5 新的测试版本的Kademlia协议实现(本文暂没覆盖)
├── enode 节点的持久化处理
│ ├── idscheme.go
│ ├── localnode.go
│ ├── nodedb.go
│ ├── node.go
│ ├── urlv4.go
├── enr 节点信息的编码处理
│ ├── enr.go
│ └── entries.go
├── message.go 节点间通信的消息封装
├── metrics.go P2P 性能指标计数器
├── nat 网络地址转换的封装
├── netutil 网络杂项功能的封装
├── peer_error.go 节点通信错误码集合
├── peer.go 通信链路的具体实现, 建立/管理/读写
├── protocol.go 抽象的子协议结构定义。
├── protocols
│ ├── accounting.go swarm 引入的消息计价 hook。
│ ├── protocol.go 协议spec的实现框架
├── rlpx.go DH 握手协议 以及包文加解密 RLPx 协议实现
├── server.go 总的入口, P2P 服务器实例, 所有功能聚合。
├── simulations P2P 综合模拟测试

P2P Server 万事开头难

初始化的路径

根据之前的Node/Service 的分析, 我们可以发现
P2P Server 是于 Node 初始化时创建的。
src_root/node/node.go line 138

```
// Start create a live P2P node and starts running it.
func (n *Node) Start() error {
......省略......
running := &p2p.Server{Config: n.serverConfig}
......省略......
if err := running.Start(); err != nil {
return convertFileLockError(err)
}
......省略......
}

top Created with Sketch.