C++盖太坊源码(01):P2P网络及节点发现体制

目录

1 分布式网络介绍

1.1 Kad网介绍

1.2 Kad网络节点距离

1.3 K桶

1.4 Kad通信协议

2 邻居节点

2.1 NodeTable类主要成员

2.2 邻居节点发现方法

2.3 邻居节点网络拓扑及刷新机制。

 

1 分布式网络介绍

以太坊底分布式网络即P2P网络,使用了经的Kademlia网络,简称kad。

1.1 Kad网介绍

Kademlia于2002年由于美国纽约大学的PetarP.Manmounkov和DavidMazieres提出,是一律种植分布式散列表(DHT)技术,以异或运算为离度量基础,已经以BitTorrent、BitComet、Emule等软件受到取应用。

 

1.2 Kad网络节点距离               

以太坊网节点距离计算办法:

 

  • Node1:节点1 NodeId

  • Node2:节点2 NodeId

 

1.3 K桶

Kad的路由表是经叫K桶的数码构造而成为,K桶记录了节点NodeId,distance,endpoint,ip等信息。以无比坊K桶按照同target节点距离进行排序,共256个K桶,每个K桶包含16单节点。

 

C++ 1

图1.1

 

1.4 Kad通信协议

    以极其坊Kad网络中节点内通信基于UDP,主要由于以下几只令成,若两独节点内PING-PONG握手通过,则当相应节点在线。

Kad通信协议,基于UDP

序号

分类

功效描述

构成

1

PING

探测一个节点,判断其是否在线

struct PingNode

{

         h256  version = 0x3;

         Endpoint  from;

         Endpoint  to;

         uint32_t  timestamp;

};

2

PONG

PING命令响应

struct Pong

{

                       Endpoint to;

                       h256 echo;

                       uint32_t timestamp;

};

3

FINDNODE

向阳节点查询有与对象节点ID距离接近的节点

struct FindNeighbours

{

                       NodeId target;                 uint32_t timestamp;

};

4

NEIGHBORS

FIND_NODE命令响应,发送和对象节点ID距离接近的K桶中的节点

struct Neighbours

{

                       list nodes: struct Neighbour

                       {

                                    inline Endpoint endpoint;

                                      NodeId node;

                       };

                       

                       uint32_t timestamp;

};

 

2 邻居节点

2.1 NodeTable类主要成员

C++版本以太坊源码中,NodeTable是坐太坊 P2P大网的根本类,所有与邻里节点相关的多寡及办法皆是因为NodeTable类实现。

 

序号

成员名称

说明

备注

1

m_node

本节点,包含NodeId、endpoint、ip等

 

2

m_state

K桶,包含邻居节点的NodeId、distance、endpoint、ip

 

3

m_nodes

已知的节点信息,但并没有加入到K桶

 

 

序号

函数名

路径

功能

1

NodeTable::NodeTable(ba::io_service&  _io, KeyPair const& _alias, NodeIPEndpoint const& _endpoint, bool  _enabled)

 

cpp-ethereum

/libp2p/NodeTable.cpp

NodeTable类构造函数,初始化K桶,发起邻居节点发现过程

2

void  NodeTable::doDiscovery()

Cpp-ethereum

/libp2p/NodeTable.cpp

具体发现函数

3

shared_ptr<NodeEntry>  NodeTable::addNode(Node const& _node, NodeRelation _relation)

cpp-ethereum

/libp2p/NodeTable.cpp

将节点加入m_nodes,并发起ping握手

4

void  NodeTable::doDiscover(NodeID _node, unsigned _round,  shared_ptr<set<shared_ptr<NodeEntry>>> _tried)

cpp-ethereum

/libp2p/NodeTable.cpp

底层发现函数,从k桶中选出节点,发送FINDNODE命令

5

vector<shared_ptr<NodeEntry>>  NodeTable::nearestNodeEntries(NodeID _target)

cpp-ethereum

/libp2p/NodeTable.cpp

从K桶中选出节点

6

void  NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from,  bytesConstRef _packet)

cpp-ethereum

/libp2p/NodeTable.cpp

Kad协议处理

7

void  NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint  const& _endpoint)

cpp-ethereum

/libp2p/NodeTable.cpp

将新节点加入到K桶

 

2.2 邻居节点发现方法

     邻居节点是乘在到K桶,并通过PING-PONG握手的节点。

C++ 2

图2.1

 

邻居节点发现流程说明:

  1. 系统率先软启动以机生成本机节点NodeId,记否LocalId,生成后以固定不换,本地节点记否local-eth。

  2. 网读取公共节点信息,ping-pong握手完成后,将那个写副K桶。

  3. 网各隔7200ms刷新一不良K桶。

  4. 刷新K桶流程如下:

a.      随机生成靶子节点Id,记否TargetId,从1开记录发现次数与刷新时。

b.      计算TargetId与LocalId的距离,记为Dlt

c.      K桶中节点的NodeId记为KadId,计算KadId与TargetId的去,记为Dkt

d.      找出K桶中Dlt大于Dkt的节点C++,记否k桶节点,向k桶节点发送FindNODE命令,FindNODE命令包含TargetId

e.      K桶节点收到FindNODE命令后,同样实行b-d的过程,将从今K桶中找到的节点使用Neighbours命令发回为本机节点。

f.       本机节点收到Neighbours后,将接纳的节点写副到K桶中。

g.      若搜索次数不超8蹩脚,刷新时未跳600ms,则赶回到b步骤循环执行。

   

2.3 邻居节点网络拓扑及刷新机制。

C++ 3

图2.2

 

1 TargetId为随机生成的虚构节点ID。

2 以极其坊Kad网络和俗Kad网络的分:

  1. 坐太坊节点在意识邻居节点的8破巡回中,所查找的节点都于距离达望自由变化的TargetId收敛。

  2. 民俗Kad网络发现节点时,在去达到于节点本身没有。

 

正文由HPB(芯链)团队整治。