以太坊源码解读(9)以太坊的P2P模块解析——底层网络构建和启动

本文深入解读以太坊的P2P模块,分为三层:底层的路由表与节点管理,中层的peer和message处理,以及顶层的以太坊特定封装。探讨了p2p.Server的启动流程,包括生成路由表、启动DialState以及监听本地接口。此外,详细介绍了peer的运行机制,包括pingLoop和ReadLoop,以及如何处理不同类型的message。
摘要由CSDN通过智能技术生成

以太坊的底层p2pServer,大约可以分为三层:

1、底层:table对象、node对象,它们分别定义了底层的路由表以及本地节点的数据结构、搜索和验证;
    1)database.go         //封装node数据库相关操作
    2)node.go             //节点数据结构
    3)ntp.go              //同步时间 
    4)table.go            //路由表
    5)udp.go              //网络相关操作

2、中层:peer对象定义了远端节点、message对象开放发送接口、server对象则提供peer节点的检测、初始化、事件订阅、状态查询、启动和停止等功能;
    1)dial.go          //封装一个任务生成处理结构以及三种任务结构中(此处命名不太精确)
    2)message.go       //定义一些数据的读写接口,以及对外的Send/SendItem函数
    3)peer.go          //封装了Peer 包括消息读取  
    4)rlpx.go          //内部的握手协议
    5)server.go        //初始化,维护Peer网络,还有一些对外的接口

3、顶层:在eth/peer.go中对p2p/peer.go的peer再封装,包含了对该节点广播的更多区块链的信息,如交易、交易hash、区块以及区块头hash等。peer最终会被收集在peerset中使用。
    1)eth/peer.go    // 封装了peer和peerset两个结构体以及一些广播数据的方法
    2)eth/handler.go  // 封装了很多协议管理工具

一、p2p.Server基本结构

Server用于管理所有的peer连接:

type Server struct {
	// Config包含了所有Server的配置选项,Service第一启动的时候Config未必初始化
	Config

	// 用于测试的hooks
	newTransport func(net.Conn) transport
	newPeerHook  func(*Peer)

	lock    sync.Mutex // protects running
	running bool

	ntab         discoverTable  // 包括Self()、Close()、Resolve()、Lookup()、ReadRandomNodes()等函数的接口
	listener     net.Listener
	ourHandshake *protoHandshake // 协议握手的RLP结构
	lastLookup   time.Time
	DiscV5       *discv5.Network // 基于V5发现协议的topic-discovery网络

	// 下面是关于peer的操作
	peerOp     chan peerOpFunc
	peerOpDone chan struct{}

	quit          chan struct{}
	addstatic     chan *discover.Node
	removestatic  chan *discover.Node
	addtrusted    chan *discover.Node
	removetrusted chan *discover.Node
	posthandshake chan *conn
	addpeer       chan *conn
	delpeer       chan peerDrop
	loopWG        sync.WaitGroup // loop, listenLoop
	peerFeed      event.Feed
	log           log.Logger
}

再看看Server的配置:

type Config struct {
	
	PrivateKey *ecdsa.PrivateKey `toml:"-"`  // 本地节点的秘钥
	MaxPeers int  // 可连接的节点最大数值

	// maxpendingpeer是在握手阶段中可以挂起的最大对等点数量,分别计算入站连接和出站连接。预设值的默认值为零
	MaxPendingPeers int `toml:",omitempty"`

	// 拨号比率控制入站与拨号连接的比率。例如:拨号比率为2允许1/2的连接被拨号。设置拨号比率为零默认为3。
	DialRatio int `toml:",omitempty"`

	NoDiscovery bool // NoDiscovery 用来禁用节点发现机制,常用于协议debugging
	DiscoveryV5 bool `toml:",omitempty"` // DiscoveryV5 决定了是否启用topic-discovery协议

	Name string `toml:"-"` // 设置节点名称
	BootstrapNodes []*discover.Node // BootstrapNodes 用于建立与网络其余部分的连接。
	BootstrapNodesV5 []*discv5.Node `toml:",omitempty"` // BootstrapNodesV5 用于建立与网络其余部分的V5连接。

	StaticNodes []*discover.Node // 静态节点用作预先配置的连接,在断开连接时总是维护和重新连接。
	TrustedNodes []*discover.Node // 可信节点被用作预先配置的连接,这些连接总是允许连接的,甚至超过对等限制。

	// 连接可以被限制到某些IP网络。如果将此选项设置为非nil值,则只考虑与列表中包含的IP网络之一匹配的主机。
	NetRestrict *netutil.Netlist `toml:",omitempty"`

	// NodeDatabase是到数据库的路径,其中包含以前在网络中看到的活动节点
	NodeDatabase string `toml:",omitempty"`

	// 协议应该包含服务器支持的协议。为每个对等点启动匹配协议。
	Protocols []Protocol `toml:"-"`

	// 如果ListenAddr设置为非nil地址,服务器将侦听传入的连接。
        // 如果端口为零,操作系统将选择一个端口。当服务器启动时,ListenAddr字段将更新实际地址。
	ListenAddr string

	// 如果设置为非nil值,则使用给定的NAT端口映射器使侦听端口对Internet可用。
	NAT nat.Interface `toml:",omitempty"`

	// 如果拨号器设置为非空值,则使用给定的拨号器拨号出站peer连接。
	Dialer NodeDialer `toml:"-"`

	// 如果NoDial是真的,服务器将不会拨任何节点。
	NoDial bool `toml:",omitempty"`

	// 如果EnableMsgEvents被设置,那么当消息发送到peer或从peer接收到时,服务器将发出PeerEvents
	EnableMsgEvents bool

	// 日志记录器是一个自定义日志记录器
	Logger log.Logger `toml:",omitempty"`
}

配置里包括了服务可连接的节点(静态节点、信任节点、剩余节点)、节点发现机制、协议列表(包括ethereum协议)、端口控制。

二、p2p.Server的启动:sever.Start()

以太坊的启动流程可以参考之前的文章:以太坊源码解读(3)以太坊启动流程简析

<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值