主页 > imtoken苹果 > 比特币和以太坊的P2P网络详解(一)

比特币和以太坊的P2P网络详解(一)

imtoken苹果 2023-01-17 11:10:25

1、P2P原理及协议概述

P2P主要有四种不同的网络模型,也代表了P2P技术的四个发展阶段:集中式、纯分布式、混合式和结构化模型。但需要指出的是,这里所说的网络模型主要是指路由查询结构,即不同节点之间如何建立连接通道。一旦在两个节点之间建立连接,传输的特定数据就在两个节点之间。事情进展顺利。

最简单的路由方式是中心化的,即有一个中心节点,存储所有其他节点的索引信息。索引信息一般包括节点IP地址、端口、节点资源等。集中路由的优点是结构简单,易于实现。但缺点也很明显。由于中心节点需要存储所有节点的路由信息​​,当节点规模扩大时,容易出现性能瓶颈;而且还有单点故障问题。

图像.png

第二种路由结构是纯分布式的,去掉了中心节点,在P2P节点之间建立随机网络就是在P2P网络中随机建立一个新加入的节点和一个节点之间的连接通道,从而形成一个随机拓扑。新节点加入网络的方式也有很多。最简单的就是随机选择一个已有节点,建立邻居关系。与比特币一样,DNS 用于查询其他节点。 DNS 通常被硬编码到代码中。这些 DNS 服务器会提供比特币节点的 IP 地址列表,以便新节点可以找到其他节点建立连接。走道。新节点与邻居节点建立连接后,需要向全网广播,让全网知道该节点的存在。全网广播方式是节点先向自己的邻居节点广播,邻居节点收到广播消息后,继续向自己的邻居节点广播,以此类推,向全网广播。这种广播方法也称为泛洪机制。纯分布式结构没有集中式结构的单点性能瓶颈问题和单点故障问题,具有很好的扩展性,但是泛洪机制引入了新的问题,主要是可控性差的问题,包括两个更大的问题就是容易形成泛滥循环。比如节点A发送的消息经过节点B到节点C,然后节点C广播给节点A,形成一个循环;另一个难题是消息风暴的响应。问题是,如果节点A要请求的资源被很多节点所拥有,那么在很短的时间内,大量节点会同时向节点A发送响应消息,这可能会导致节点A瞬间瘫痪。

图像.png

我们来看看第三种路由结构:hybrid。 Hybrid实际上是集中式和分布式结构的混合体。如下图所示,网络中有多个超级节点组成分布式网络,每个超级节点又拥有多个普通节点,形成本地集中式网络。当有新的普通节点加入时,首先选择一个超级节点进行通信,超级节点将其他超级节点的列表推送给新加入的节点,加入节点根据超级节点决定选择哪个特定的超级节点作为父节点列表中的节点状态。这种结构的泛洪广播只发生在超级节点之间,可以避免大规模泛洪的问题。在实际应用中,混合结构是一种比较灵活有效的组网架构,实现难度相对较小。因此,目前很多系统都是基于混合结构开发和实现的。其实今天的比特币网络也是这样的结构,后面会详细讨论。

图像.png

最后一种网络是结构化的P2P网络,也是一种分布式的网络结构,但不同于纯粹的分布式结构。纯粹的分布式网络是一种随机网络,而结构化网络则是将所有节点按照一定的结构有序地组织起来,如形成环形网络或树状网络。结构化网络的具体实现一般基于**DHT(Distributed Hash Table,分布式哈希表)**算法思想。 DHT 只是提出一种网络模型,不涉及具体实现。主要是想解决分布式环境下如何快速准确的路由和定位数据的问题。具体实现方案包括Chord、Pastry、CAN、Kademlia等算法,其中Kademlia也是以太坊网络的实现算法,很多常用的P2P应用如BitTorrent、eDonkey等也使用Kademlia。由于篇幅有限,这些算法的具体原理不再赘述。目前我们主要了解DHT的核心思想。

在P2P网络中,可以抽象出两种空间:资源空间和节点空间。资源空间是所有节点保存的资源的集合,节点空间是所有节点的集合。对所有资源和节点分别编号,比如把资源名称或者内容用Hash函数变成一个值(这也是DHT常用的方法),这样每个资源都有对应的ID,每个节点也有一个A映射ID、资源ID和节点ID之间建立关系。例如,如果资源n的所有索引信息都存储在节点n上,那么在搜索资源n时,只能找到节点n,从而避免泛化。泛洪广播,可以更快更准确地路由和定位数据。当然,在实际应用中,资源ID和节点ID之间并没有一一对应的关系,但是因为ID都是数字,所以存在大小关系或者偏序关系等,基于这些关系,一个映射两者之间可以成立。关系。这是DHT的核心思想。 DHT算法采用分布式哈希表进行资源编号和节点编号,使得资源空间和节点空间的编号具有更好的唯一性和均匀分布等特性,可以满足结构化分布式网络的要求。

未来比特币和以太坊

综上所述,这就是P2P网络的理论基础。不同的区块链可能使用不同的网络模型未来比特币和以太坊,但基本原理是相同的。两个最具代表性的区块链网络将在后面解释:比特币网络和以太坊网络。

2、比特币和以太坊整体P2P网络对比分析2.1通信协议层面2.2初始节点发现

Bit 在比特币网络中,初始节点发现有两种方式:

DNS-seed,又称DNS种子节点,比特币社区会维护一些域名,通过nslookup可以解析出几十个A记录的主机IP。例如:

nc -nvv 149.202.179.35 8333

找到 0 个关联

找到 1 个连接:

1:标志=82

outif en0

src 192.168.1.104 端口 62125

dst 149.202.179.35 端口 8333

排名信息不可用

未来比特币和以太坊

可用的 TCP 辅助信息

连接到 149.202.179.35 端口 8333 [tcp/*] 成功!

硬编码一些种子节点未来比特币和以太坊,当所有种子节点失败时,所有节点都会尝试连接这些种子节点。

在以太坊中,思路大致相同,代码中硬编码了一些种子节点来做类似的工作。

2.3 启动后发现节点

在比特币网络中,一个节点可以将自己维护的peer列表发送给相邻节点,所以在初始节点发现之后,你的节点要做的第一件事就是向对方索要一个列表:“快给给我一份你的节点列表。”

所以每次需要发送协议消息时,都会花费固定时间尝试与现有节点列表中的节点建立链接。如果任何一个节点在超时之前都可以连接上,那么就不需要去DNS种子获取地址了。一般来说,这种可能性很小,尤其是在全节点数量非常多的情况下。

在以太坊网络中,也维护了一个类似的节点列表(NodeTable),但这个节点列表不同于比特币的简单维护。它采用了P2P网络协议中成熟的算法。它被称为Kademlia网络,简称KAD网络。

它使用DHT来定位资源,全称Distributed Hash Table,中文名称为Distributed Hash Table。 KAD 网络维护一个路由表,用于快速定位目标节点。由于 KAD 网络基于 UDP 通信协议,因此以太坊节点的节点发现基于 UDP。如果找到节点,数据交互将切换到TCP协议。

2.4 NAT穿越

局域网内主机IP与公网IP建立P2P连接的解决方案是做NAT穿越。

比特币和以太坊都使用 UPnP(通用即插即用)协议作为 LAN 渗透工具。只要局域网内的路由设备支持NAT网关功能,支持UPnP协议,就可以将区块链节点自动映射到公网。

未来比特币和以太坊

UPnP是Universal Plug and Play(通用即插即用)的缩写,主要用于设备的智能互联,网络上的所有设备都能第一时间知道有新设备加入。

2.5 节点交互协议

一旦一个节点建立了连接,节点之间的交互就遵循一些特定的命令,这些命令写在消息的头部,消息体就是消息的内容。

命令有两种,一种是请求命令,一种是数据交互命令。

节点需要做的第一件事就是握手操作。这个过程在比特币和以太坊中是类似的,只是互相打招呼并提供一些简短的信息。

例如,先交换版本号,看看它们是否兼容。只是以太坊为握手过程提供了对称加密,而比特币没有。

握手之后,无论交换什么信息,都需要保持长连接。比特币上有两种 PING/PONG 消息,显然是用来保持节点之间的长期连接。它是为连接的心跳而设计的;在以太坊的设计中,PING/PONG 协议被移到了节点发现的过程中。

请求命令一般分为发起者请求。比如比特币中的getaddr命令是获取对方可用节点列表,inv命令提供数据传输,消息体中会包含一个数据向量。

我们说区块链最重要的功能就是同步区块链,而同步区块恰好是最考验P2P网络能力的。有两种块同步方法。第一个叫做HeaderFirst,先提供要同步的区块头,同步完成后从其他节点获取区块体。

第二个称为 BlockFirst。这种区块同步方式比较简单粗暴,即从其他节点获取的区块必须是完整的。第一种方案提供了更好的交互过程,减少了网络负担。这两种同步方式会直接体现在节点交互协议中,它们使用的命令逻辑完全不同。

一般的P2P网络技术需要解决两个主要问题,一是资源定位,二是资源获取。本文也主要关注这两点,其中节点发现和局域网穿透属于资源定位问题,节点交互协议属于资源获取问题。

3、比特币中的P2P网络详解比特币网络

未来比特币和以太坊

首先,比特币网络中的节点有四个主要功能:钱包、挖矿、区块链数据库、网络路由。每个节点都会有路由功能,但其他功能可能不可用。不同类型的节点可能只包含一些功能。一般来说,只有比特币核心节点会包含所有四个功能。

图像.png

所有节点都会参与校验和广播交易和区块信息,并会发现和维护节点连接。有些节点会包含一个完整的区块链数据库,包括所有的交易数据,这样的节点也称为全节点。其他节点只存储区块链数据库的一部分,一般只存储区块头,不存储交易数据。他们将通过“简化交易验证(SPV)”的方式完成交易验证。此类节点也称为 SPV 节点。或轻量级节点。钱包一般是PC或手机客户端的功能。用户可以通过钱包查看账户金额,管理钱​​包地址和私钥,发起交易。大多数钱包都是轻节点,除了比特币核心钱包是全节点。挖矿节点通过解决工作量证明(PoW)算法问题与其他挖矿节点竞争以创建新块。有些挖矿节点也是全节点,也就是存储了一个完整的区块链数据库。这样的节点通常是 Solo Miners。还有一些挖矿节点不是独立挖矿,而是与其他节点一起接入矿池参与集体挖矿。这种节点通常也称为矿池矿工。这样就形成了一个本地集中的矿池网络,中心节点是矿池服务器,其他所有的挖矿节点都连接到矿池服务器。矿池矿工与矿池服务器之间的通信不使用标准的比特币协议,而是使用矿池挖矿协议,矿池服务器作为全节点,与其他比特币节点使用主网比特币协议。交流。

在整个比特币网络中,除了主网使用比特币协议作为不同节点之间的通信协议外,还有很多扩展网络,包括上面提到的矿池网络。不同的矿池网络也可能使用不同的矿池挖矿协议。目前主流的具体矿池协议应该是Stratum协议,不仅支持挖矿节点,还支持瘦客户端钱包。一个扩展的比特币网络,包括比特币协议主网和Stratum网络的各个节点,以及其他矿池网络,大致如下:

图像.png

此外,对于挖矿也有特殊要求。我们知道,矿工创建新区块后,需要向全网所有节点广播。当全网接受该区块时,给予矿工的挖矿奖励有效,然后就可以开始下一个区块Hash。计算。所以矿工必须尽量减少广播新区块和计算下一个区块哈希之间的时间。如果矿工之间的区块传播只使用上图所示的比特币协议网络,无疑会出现很高的网络延迟。因此,需要一个专门的传播网络来加速新区块在矿工之间的同步传播。这个专门的网络也称为比特币传播网络或比特币中继网络。

4、以太坊中的P2P网络详解以太坊网络

和比特币一样,以太坊节点也有钱包、挖矿、区块链数据库,网络路由的四大功能也有很多不同类型的节点。除了主网之外,还有很多扩展网。但与比特币不同的是,比特币主网的 P2P 网络是非结构化的,而以太坊的 P2P 网络是结构化的。前面我们提到,以太坊的P2P网络主要是通过Kademlia(简称Kad)算法实现的,这是一种分布式哈希表(DHT)技术。准确路由和定位数据的问题。因此,以下主要讲解以太坊的Kad网络。

在 Kad 网络中,每个节点都有一个唯一的节点 ID。另外,还计算了不同节点之间的距离,但是这个距离不是物理距离,而是逻辑距离,是通过对两个节点ID(符号^)进行异或运算得到的,也就是A,计算公式B的两个节点之间的距离为:D(A,B) = A.ID^B.ID。 XOR 有一个重要的性质:假设 a、b、c 是任意三个数,如果 a^b = a^c 成立,则 b = c。因此,给定一个节点a和一个距离L,只有一个节点b,使得D(a,b) = L。这样可以有效地测量Kad网络中不同节点之间的逻辑距离。

基于异或距离度量,Kad还可以将整个网络拓扑组织成如下图所示的二叉前缀树,每个NodeID都会映射到二叉树上的一个叶子。

未来比特币和以太坊

图像.png

主要的映射规则有:

以二进制形式表示NodeID,然后转换为从高到低依次处理每一位的0或1;二进制的第n位对应二叉树的第n层;如果该位为 0,则进入左子树,如果为 1,则进入右子树(反之亦然)。是的);处理完所有位后,这个 NodeID 对应于二叉树上的一个叶子。

在这个二叉树结构中,对于每一个节点,离它越近的节点,异或距离就越近。然后,您可以根据与自己的异或距离来拆分整个二叉树。分裂规则是:从根节点开始,分裂不包含自身的子树,再将不包含自身的子树分裂到包含自身的子树中,以此类推。 ,直到只剩下你。以上图中的110节点为例,从根节点开始,由于110节点在右子树中,所以左边的整个子树被分裂,即包括三个000、00 1、010 每个节点的这个子树;然后,对二级子树,将不包含110个节点的左子树,即包含100和101两个节点的子树进行拆分;最后,再次拆分111。分开它。这样一来,除了110个节点之外,整棵二叉树就被分成了三个子树。

子树分裂后,只要知道每个子树中的一个节点,就可以进行递归路由遍历整个二叉树中的所有节点。但是在实际场景中,由于节点是动态变化的,一般每个子树不仅知道一个节点,还需要知道多个节点。因此,Kad中有一个叫做K-bucket的概念,每个bucket会记录每个子树中已知的多个节点。实际上,一个 K-bucket 就是一个路由表。如果有m个子树,则对应的节点需要维护m个路由表。每个节点都会维护自己的 m 个 K-buckets。每个 K-bucket 中记录的节点信息一般包括 NodeID、IP、Endpoint 以及与 Target 节点(即维护 K-bucket 的节点)的异或距离。和其他信息。在以太坊中,每个节点维护的 K-buckets 数量为 256 个。这 256 个 K-buckets 将根据与 Target 节点的 XOR 距离进行排序。每个K-bucket存储的节点数上限为16个。

在以太坊的Kad网络中,节点之间的通信是基于UDP的,主要设置了4种通信协议:

Ping:用于检测某个节点是否在线 Pong:用于响应Ping命令 FindNode:用于查找异或距离目标节点最近的其他节点 Neighbours:用于响应FindNode命令,一个或多个节点将被返回

通过以上4条命令,可以实现增加新节点、刷新K-buckets等机制。具体实现过程就不详细讨论了,留给大家自己思考吧。

总结

不同结构的P2P网络有不同的优缺点。比特币网络的结构显然很容易理解,实现起来也相对容易,而以太坊网络则引入了异或距离、二叉树、K-bucket等。结构要复杂得多,但在节点路由。比比特币快得多。另外,无论是比特币还是以太坊,其实只是一个或多个协议的集合,不同的节点其实可以使用不同的具体实现。例如,比特币有用 C++ 实现的 Bitcoin Core,以及用 Java 实现的 BitcoinJ。 以太坊也有 Go 语言实现的 go-ethereum、C++ 实现的 go-ethereum 和 Java 实现的 Ethereum(J)。

思考与实践

在以太坊的Kad网络中,添加新节点和刷新K-bucket的过程是怎样的?加入比特币新节点的流程是什么?哈希表有哪些实现方式?