以太坊源码解读(8)以太坊的P2P模块解析——节点发现和K-桶维护

本文详细解读了以太坊P2P网络中的Kademlia协议实现,包括K-桶的结构与维护,table对象的初始化、种子节点加载、数据库刷新以及节点查找的通信协议。以太坊采用K-桶策略,每个桶存储16个节点,通过异或计算节点间的距离,并定期刷新维护节点列表。
摘要由CSDN通过智能技术生成

回顾一下,前面说到以太坊分布式网络采用了Kademlia协议,它的特点是:
1、采用了二叉树的拓扑结构;
2、每个节点都对整树进行拆分,分成n棵子树;
3、从每棵树中取K个节点,构成“k-桶”,每个节点控制着n个k-桶;
4、节点的距离是通过异或的二进制运算得到的;
5、k桶中的节点不是固定不变的,而是不断刷新变化的。

下面,我们来看看Kademlia协议在以太坊中的具体实现。

一、以太坊的k桶

以太坊的k值是16,也就是说每个k桶包含16个节点,一共256个k桶。K桶中记录了节点的NodeId,distance,endpoint,ip等信息,按照与target节点的距离进行排序。

distance 0:[2^0, 2^1) node0 node1 node2 ... node15
distance 1:[2^1, 2^2) node0 node1 node2 ... node15
distance 2:[2^2, 2^3) node0 node1 node2 ... node15
distance 3:[2^3, 2^4) node0 node1 node2 ... node15
... node0 node1 node2 ... node15
distance 255:[2^255, 2^256) node0 node1 node2 ... node15

这个表在源码里为Table对象(p2p/discover/table.go):

type Table struct {
	mutex   sync.Mutex        // protects buckets, bucket content, nursery, rand
	buckets [nBuckets]*bucket // index of known nodes by distance
	nursery []*Node           // bootstrap nodes
	rand    *mrand.Rand       // source of randomness, periodically reseeded
	ips     netutil.DistinctNetSet

	db         *nodeDB // database of known nodes
	refreshReq chan chan struct{}
	initDone   chan struct{}
	closeReq   chan struct{}
	closed     chan struct{}

	nodeAddedHook func(*Node) // for testing

	net  transport
	self *Node // metadata of the local node
}

这里有几项是比较重要的:
1)buckets    类型是[nBuckets]*bucket,可以看到这是一个数组,一个bucket就是一个K-桶,一共256个bucket;
2)nursery    信任的种子节点,一个节点启动的时候首先最多能够连接35个种子节点,其中5个是由以太坊官方提供的,另外30个是从数据库里取的;
3)db    以太坊中有两个数据库实例,一个是用来储存区块链,另一个用来储存p2p的节点。
4)refreshReq    刷新K桶事件的管道,其他节点或者其他应用场景可以通过这个管道强制刷新该节点的k桶。

二、table对象的相关方法

1、newTable()新建table

task1:根据外部或默认参数初始化Table类
task2:加载种子节点
task3:启动数据库刷新go程
task4:启动事件监听go程

func newTable(t transport, ourID NodeID, ourAddr *net.UDPAddr, nodeDBPath string, bootnodes []*Node) 
(*Table, error) {
	// If no node database was given, use an in-memory one
	db, err := newNodeDB(nodeDBPath, nodeDBVersion, ourID)
	if err != nil {
		return nil, err
	}
        // 初始化Table类
	tab := &Table{
		net:        t,
		d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值