NKN 学习笔记

分布式哈希表( DHT

通常是直接拿业务数据的散列值作为 key,业务数据本身作为 value。可以简单而快速地进行put、get。

Chord 协议

原理 :Chord通过把Node和Key映射到相同的空间而保证一致性哈希,为了保证哈希的非重复性,Chord选择SHA-1作为哈希函数,SHA-1会产生一个2^160的空间,每项为一个16字节的大整数。这些整数首尾相连形成一个环,称之为Chord环。整数在Chord环上按大小顺时针排列,Node(机器的IP地址和Port)与Key(资源标识)都被哈希到Chord环上,这样就假定了整个P2P网络的状态为一个虚拟的环。

覆盖网络

在一个含有N个节点的网络中,将整个网络看做一个圆环,节点按标识符从小到大顺时针组成一个环。对象分配在节点n上,n是从节点标识符大于等于对象标识的节点开始顺时针方向遇到的第一个活着的节点。

数据查找

每个节点都维护一个Finger表,该表长度为m(m就是位数,在Chord中为160),该表的第i项存放节点n的第(n+2^i-1) mod 2^m个successor(1<=i<=m)。

每个节点都维护一个predecessor和successor列表,该列表的作用是能快速定位前继和后继,并能周期性检测前继和后继的健康状态。就是说存放的successor是按2的倍数等比递增,之所以取模是因为最后的节点的successor是开始的几个节点,比如最大的一个节点的下一个节点定义为第一个节点

资源Key存储在下面的Node上:沿Chord环,hash(Node)>=hash(key)的第一个Node,我们称这个Node为这个Key的successor。

给定一个Key,按下面的步骤查找其对应的资源位于哪个节点,也就是查找该Key的successor:(假如查找是在节点n上进行)

1 查看Key的哈希是否落在节点n和其直接successor之间,若是结束查找,n的successor即为所找。

2 在n的Finger表中,找出与hash(Key)距离最近且小于hash(Key)的n的successor,该节点也是Finger表中最接近Key的predecessor,把查找请求转发到该节点。

3 继续上述过程,直至找到Key对应的节点。

查询过程实际上就是折半查找的过程。虽然Chord中的每个节点维护了O(log(N))个信息,但是Chord协议提高了数据路由和定位的效率,从O(N)提高到了O(log(N)),查询时信息的转发也减少到了O(log(N))。

NKN 网络

协议

Chrod DHT不是业界最受欢迎的DHT。选择Chord DHT的原因是它的可验证性。尽管具有更复杂的协议,但是Chrod DHT具有独特的优点,即在所有节点在环上寻址的情况下,邻居和路由的选择是确定性的。两者都可以验证任何其他节点。

设备

NKN网络中有两种主要类型的设备:节点和客户端。节点是一种发送,接收的设备,最重要的是中继数据。客户端是仅发送和接收数据但不中继数据的设备。客户端通过节点与NKN网络的其余部分进行交互。

节点是NKN网络的维护者和贡献者,因此可以获得奖励。节点需要具有公共IP地址才能从尚未与其建立连接的节点接收消息。客户端是NKN网络中的消费者,其向节点支付中继数据或通过节点接收数据。客户端不需要具有公共IP地址,因为它将与节点建立连接,然后通过它们发送和接收数据。

选址方案

节点:

节点的NKN地址是随机的(或者至少是均匀分布和不可控制的),原因有两个。首先,恶意节点很难选择特定的NKN地址。能够选择NKN地址使得恶意节点更容易攻击系统,因为邻居和路由基于NKN地址。其次,给定随机NKN地址的节点之间的负载更加平衡,有效地使网络更分散。

为了保证NKN地址的随机性并防止恶意节点选择特定的NKN地址,当节点加入NKN网络时,使用唯一的,不可预测的,不可控制但仍可验证的功能来生成NKN地址。我们在节点加入时选择公共IP地址和最新块哈希的哈希

节点NKN地址=Hash(节点公共IP地址,最新块哈希)

这样它可由其他节点验证,但事先无法预测。

客户端:

客户端具有与节点不同的NKN地址方案。该计划应满足以下属性:

1客户端NKN地址是永久性的,以便在不同的物理网络中可以从相同的NKN地址到达客户端。

2客户端NKN地址与其公钥相关联,以避免NKN地址冲突,这样其他客户端无法接收发送给它的数据包。

我们选择这样的方案,使得客户端NKN地址是从类似URL的NKN地址字符串计算的,该字符串由客户端选择的任意字符串及其公钥组成。

客户端NKN地址= Hash(“arbitrary-string.client-public-key”)

在NKN地址字符串中,由点(客户端公钥)分隔的最后一个子字符串表示客户端的唯一标识,类似于URL中的根域; 其余部分由客户端选择,类似于URL中的子域。这种方案满足上述两个特性。此外,用户(密钥对持有者)可以生成与他想要共享相同帐户一样多的NKN地址。

客户端不直接分发其NKN地址。相反,客户端将其NKN地址字符串分发给节点或其他客户端,并且它们在本地计算客户端的NKN地址,以便它们同时知道客户端的NKN地址和公钥。使用这种方案,任何客户端之间的端到端加密都很容易实现。

距离度量

从NKN地址x到y的距离定义为

dist(x,y)=(y - x)mod 2 ^ m

满足以下条件:

dist(x,y)> = 0

当且仅当x = y时,dist(x,y)= 0

dist(x,z)<= dist(x,y)+ dist(y,z)

dist(x,y)= dist(x + a,y + a)

距离度量是不对称的,dist(x,y)通常不等于dist(y,x)。

网络拓扑

任何NKN地址x的后继节点和前驱节点如下:

successor(x)= argmin_y {dist(x,y)| y在所有节点中}

predecessor(x)= argmin_y {dist(y,x)| y在所有节点中}

NKN网络中的每个节点x都有一些邻居:

后继(x + 2^i)mod 2^m(0 <= i <m)和 前继y

由于并非所有NKN地址都分配给节点,因此上面的一些邻居指向同一节点。节点的预期邻居数是O(log(N))。

可验证性

每个邻居的选择可以由至少一个其他节点来验证。假设地址x处的节点应选择A作为其第i个后继节点。在这种情况下,地址(x+2^i)mod 2^m和A之间没有节点,并且A应该从其前任知道该信息。因此A知道它本身应该是x的邻居。如果节点x没有选择A作为邻居,则A能够伪造它。类似地,如果x选择A和(x+2^(i+1))mod 2^m之间的另一个节点以及A作为邻居,A也应该能够伪造它。可验证性对于可能具有非常重要的恶意节点部分的开放网络至关重要。

路由

给定已建立的NKN网络,可以仅使用关于邻居的信息在贪心算法中实现路由。当节点想要将数据包发送或中继到目标地址时,它会将数据包发送到距目标地址最小的邻居。剩余距离最多变为每个中继的前一个值的一半,因此在中继分组时指数或更快地减小。与Chord DHT类似,在给定均匀分布的地址的情况下,预期的跳数是O(log(N))。

如果目标地址是客户端而不是节点,则只要数据包到达连接到客户端的节点,上述路由就会停止。然后,节点通过建立的连接将数据包中继到客户端。

任何两个节点对之间的路由都是可验证的。假设发送数据包到目的地址D的节点应该选择其邻居A作为下一跳,而实际上选择了邻居B,从路由规则我们知道dist(A,D)<dist(B,D)。然后A能够伪造路线。如果节点选择非邻居节点作为下一跳,则如前所述,这种路由可以被实际邻居伪造。路由的可验证性对于降低形成仅由恶意节点组成的路由的可能性是至关重要的。

协议

NKN网络是一个开放的网络。节点都可以随时加入和离开网络。为了有效地维护NKN网络,每个节点在本地维护三个列表:

1 它的继承者和前辈。需要至少一个后继者和一个前任者,同时在列表中保留更多节点增强了容错性。

2 它的邻居。

3 连接到它的客户端。

节点会更新这些列表以响应拓扑更改。为了提高效率,重要的是当节点或客户端加入或离开网络时,只有一小部分其他节点(最多为O(logN))是更新。

节点加入

当节点想要加入NKN网络时,它需要知道已经在网络中的至少一个其他节点。我们为此提供引导服务器,同时也可以使用其他源。在与NKN网络中的至少一个其他节点取得联系后,它将执行以下过程:

1请求最新的块哈希来计算自己的NKN地址x。

2发送消息给后继者(x)和前任者(x)以获得其继承者和前任者。

3向其邻居询问其继任者和前任。

4使用其前任的后继邻居和其后继的前任邻居来识别邻居。对于无法确定的邻居,将消息发送到理论NKN地址以获取实际邻居地址。

5确定需要使用其后继者和前任者的邻居列表更新其邻居的节点。通知这些节点更新邻居。

6接管其前任的响应客户。

节点离开

当节点想要离开NKN网络时,它执行以下过程:

通过向邻居发送其后继者或前任来通知邻居更新他们的邻居。

1将其响应客户端交给其前身。

2如果节点发生故障(不执行上述过程而离开),其邻居会注意到这一点并将其从列表中删除。连接到它的客户端将在连接到新节点之前获取更新的节点以连接到网关。

客户加入

当地址x处的客户端想要加入网络时,它与网络中的至少一个节点联系,并要求前任(x)获得它应该连接的节点。然后它连接到前任(x)。

客户离开

当客户端想要离开网络时,它会通知其连接的节点将其从客户端列表中删除。

如果客户端发生故障,其连接的节点会在建立的连接失败时注意到这一点。然后节点从列表中删除客户端。

共识和区块链

共识议定书

使用MOCA算法在节点之间达成共识。MOCA在时间和消息计数方面都很有效,因为只需要在邻居之间进行几次通信迭代即可达成共识。

共识所需的信息(例如,下一个块)在共识开始时通过类似gossip协议发送给所有参与节点,该协议占用O(logN)时间,这是共识过程的主要时间成本。这个时间可以减少到O(logN / logk),因为可以在未来的版本中实现类似于Kademlia DHT的多达k倍的邻居。

共识算法可以由共识消息触发的事件驱动协议来实现。每条共识消息都有一个主题ID,用于标识正在达成一致的内容。对于从邻居收到的关于二进制状态的每个共识消息(例如,接受或拒绝一个块),执行以下过程:

1如果它是具有主题id的第一条消息,则计算自身初始状态并将状态发送给邻居。

2更新主题ID的发件人状态。

3如果选择self作为邻居的节点中有一半以上具有来自主题id的自身状态的另一个状态,则将自身状态更改为多数状态并将状态发送给邻居。

自首次接收具有相同主题ID的消息后的固定时间量后,主题ID的共识过程将停止。

中继证明

NKN网络中的一个关键问题是证明节点中继了多少数据,我们将其定义为中继证明(PoR)。PoR对于NKN网络至关重要,因为被中继的数据量与奖励直接相关。理想的证据应满足以下条件:

  1. 1.可验证:任何参与数据传输的人都能够仅使用公共信息正确验证证据;
  2. 2.不可伪造:任何一方,除非控制所有相关节点,否则能够伪造一份具有非平凡概率的有效证据;

(3)不可篡改:除非控制所有涉及的节点,否则任何一方都无法修改具有非平凡概率的有效证据。

我们使用签名链来解决问题。为了提高效率,我们使用链的散列以无法控制但可验证的方式随机选择证明。此外,我们选择了一类证据,即使对于控制了网络中所有节点的很大一部分的大型恶意方也有资格获得其他好处(例如挖掘奖励),这些证明也难以伪造。

签名链作为中继的证明

NKN网络的主要功能之一是传输数据。为了对更高级别的应用程序透明,NKN网络使用网络数据包。数据包源自可以是节点或客户端的源,然后由只能是节点的中继器中继,最后到达可以是节点或客户端的目的地。

NKN 数据包

NKN网络中的基本传输单元是NKN分组。NKN数据包包含以下字段:

1有效负载(例如网络数据包)

2有效载荷哈希

3有效载荷大小

4来源NKN地址和公钥

5目的地NKN地址和公钥

6签名链

签名链

签名链是签名链在转发NKN数据包时由数据中继器顺序签名。链中的每个元素都包含以下字段:

1 Relayer NKN地址和公钥

2 下一个继电器NKN地址

3 签名(链上的前一个元素的签名,中继NKN地址,下一个中继NKN地址)与中继私钥签名​​

签名链的第一个元素由源签名,签名字段由签名(有效负载散列,有效负载大小,源NKN地址和公钥,目标NKN地址和公钥,下一个中继NKN地址)替换。

可验证

当且仅当链上的每个元素满足以下条件时,签名链才有效:

1中继NKN地址匹配前一个元素的下一个中继NKN地址。

2 签名字段有效。

除有效负载外,对签名NKN数据包的任何修改都将使签名链无效,除非重新签名。因此,签名链可以被任何有权访问NKN数据包的人验证(不需要有效载荷)。如果没有沿路线的所有私钥,恶意方不能篡改或伪造签名链。

当且仅当满足以下条件时,NKN数据包才有效:

1有效负载哈希是正确的。

2有效载荷大小是正确的。

3签名链是有效的。

4源NKN地址和公钥匹配签名链的第一个元素。

5目的地NKN地址和公钥匹配签名链的最后一个元素

除非重新签名,否则对签名的NKN数据包的任何修改都将使其无效。因此,NKN数据包对任何人都是可验证的。验证NKN数据包不需要额外的信息。如果没有沿路由的所有私钥,恶意方不能篡改或伪造NKN数据包。

PoR 证明

我们使用带有有效载荷字段的NKN数据包作为沿路由的所有中继节点的中继工作的证明。它满足了我们可验证,不可伪造和无法满足的要求,这样每个人都能够验证签名链的有效性,而没有人可以伪造或修改有效的签名链而无需控制(拥有私钥)路由中的所有节点。

签名链不能伪造,因为每个元素包含下一个节点的NKN地址和公钥。如果路由上的节点是恶意的,并在生成其签名时删除或修改链上的某些先前元素,则链不再有效。类似地,如果恶意方拦截了部分签名的签名链,则在没有指定的下一节点的私钥的情况下不能生成有效的签名链。

高效的 PoR 证明

每个NKN数据包都有一个证据,可以用作收据来生成从源到中继器的事务。然而,为NKN网络中传输的每个分组创建事务是低效的。相反,只有签名链上的最后签名小于阈值的数据包才有资格进行交易。

签名链上的最后一个签名对每个人都是可验证的,但仍然是不可预测和不可控制的,除非沿着包括源和目的地的路径上的所有节点都由同一方控制。给定有效载荷和完整路径,最后一个签名基本上是确定性的,但如果没有沿路由的所有私钥,则无法提前计算。

使用理想的散列函数,签名链上的最后一个签名是跨数据包的随机签名。因此,仅选择具有足够小的最后签名用于交易的分组(具有经调整的每个分组的价格)不会改变中继节点的预期奖励,而是引入定价和奖励的一些变化。应选择阈值以平衡较少交易和较小奖励变化的需要。

基于会话的传输

对于繁重的网络流量,为每个数据包建立签名链是低效的。这里我们介绍另一个名为session的概念。当用户想要与另一个NKN节点通信时,他们可以建立会话以避免对每个数据包进行签名。

我们有两个不同版本的协议,一个确定性版本和一个概率版本。我们在早期实现确定性版本,因为它更简单。如果NKN中有数万用户,则区块链的吞吐量成为瓶颈。我们正在设计一个概率版本来减少区块链上的数据。两个不同版本共享许多类似的想法,因此我们同时介绍其中两个。

建立会议

为了建立会议,参与者需要就以下事项达成一致:

1会话的所有者。(谁来支付它。)

2所有者选择的时间戳。

3指定会话路径的中继列表。(最后一个元素称为目标)

每个中继元素应包含以下部分

1公钥

2价钱

3哈希Anchor

这部分称为此会话的元数据。对这些元数据达成共识可以基于签名链和一些其他市场匹配和讨价还价机制。我们在这里跳过细节。

生成元数据后,我们为此元数据构建签名链。元数据和签名的哈希值是会话ID。

数据传输

基于会话的传输可以显着降低每个数据包的平均开销。每个数据包只需要包含一个包含以下内容的标头:

1会话ID

2方向(所有者→目的地或目的地→所有者)

3 Nonce(两个方向的nonce分别计数。)

注意:这里的术语“数据包”不是网络层中的IP数据包,它是数据传输中的基本计费单元。发送方可以确定如何将所有传输数据划分为数据包。例如,GET请求,HTTP请求的响应。每个数据包不应该太大。(例如,<1MB)

块创建

通过选择提出新块的“领导者”,将新块添加到区块链中。领导者选择是无法控制但可验证的。节点被选为领导者的预期概率与节点在安全路径上中继的数据成正比。选定的领导者建议下一个块并将其发送到网络进行确认。如果达到节点之间的一致性,则建议的块将作为下一个块添加到区块链中。

领导者选择

首先在安全路径上选择签名链来选择领导者。选择的签名链是具有最低最后签名值的签名链。如前所述,在恶意方控制链中的所有节点之前,不能预测或伪造签名。另一方面,任何恶意方都有可能控制安全路径上的所有节点。这两个属性相结合,保证在安全路径上选择具有最低最后签名的签名链实际上是在安全路径上随机选择签名链,并且任何一方都无法预测或控制选择。

为了选择具有最低最后签名的签名链,签署最后签名的每个节点检查最后签名是否小于阈值。如果最后一个签名小于阈值,则节点将签名链发送到网络,作为最后一个签名的候选者。选择阈值使得具有高概率的最低最后签名小于阈值。令t为以最大可能签名值为单位的阈值,并且签名从0到最大值均匀分布。所有最后签名都高于阈值的概率是(1-t)^ L,其中L是签名链的数量。我们需要(1-t)^ L <e,其中e足够小。对于t,我们有t> - (log e)/ L。我们选择t = - (log e)/ L来最小化候选者的数量。

在接收候选人之后,节点就签名链选择达成共识。每个节点的初始选择是具有最低最后签名的签名链候选。如果所有节点都接收到相同的候选者,则共识是微不足道的,因为所有诚实节点将做出相同的初始选择。否则,共识协议将保证相同的签名链(但不一定是具有全局最低签名的签名链,如果最初它没有被足够的节点接收)。

当达到关于签名链的共识时,从签名链中选择确定性的领导者。设S是签名链的最后一个签名。签名链上的中继节点标记为0到L-1,其中L是中继节点的数量。然后,领导者是签名链上具有标签S mod L的节点。

块创建

块是由每一轮选定的领导者提出的。建议的块被发送到所有节点以进行验证和达成共识。在共识阶段期间,每个节点向其邻居发送块的散列(如果领导者向不同的邻居发送不同的块)以及是否接受。达成共识时,所有节点应具有相同的已接受块,否则应拒绝。如果接受,建议的块将添加到区块链中。

恶意节点

首先,假设一个节点是好的,或者是恶意的,并且永远保持不变。

我们考虑的攻击模型如下。N个节点中有M个恶意节点。攻击是成功的是恶意节点可以强制共识收敛到少数而不是大多数诚实节点的初始状态。恶意节点可以向其邻居发送任意投票,而不是遵循共识协议,但是他们无法更改其邻居,因为我们选择的拓扑是可验证的。我们考虑这种攻击模型的原因是,如果攻击者可以强制诚实节点收敛到少数群体状态,那么他们基本上可以控制共识结果,或者让它收敛到任何状态,或者让它根本不收敛。

我们发现攻击是否成功取决于两个参数:系统中有多少恶意节点和诚实节点初始状态的分布。例如,如果所有诚实节点最初处于相同状态,那么我们需要相当多的恶意节点,实际上是N / 3左右,以迫使所有诚实节点改变他们的意见。但是,如果诚实节点具有相当平衡的初始状态,那么只有少量恶意节点足以打破任何方向的平衡,从而控制共识结果。我们称这样的属性为条件-BFT(拜占庭容错) - 也就是说,共识是否是BFT取决于初始条件。我们最终使用系统设计的其他部分来帮助网络保持在BFT区域。

路由效率

NKN的路由效率高于传统中心化网络的路由效率。NKN为了防止恶意节点破坏网络,需要对路由随机化。随机化路由也导致效率更低,因为它无法做到最短路径最快速度的发送数据包。NKN提出了权衡的办法,NKN节点的每个链接都可知道其ping时间,因此从给定节点,可以选择最低延迟的节点。此外,在发送方和接收方之间可以创建多个并发NKN路由。这样一来,甚至可以聚合所有虚拟路径的带宽。这也是NKN的网络加速器的原理,它可以实现167%—273%的速度提升。而且文件越大,提升越好。Web下载的瓶颈不再是内容服务器,也不是用户的ISP,而是在于默认的网络路由路径。

奖励

首先NKN节点的贡献是基于它的“工作量证明”,而这个工作量证明跟比特币的挖矿算力证明不同,它涉及的是在NKN网络上中继的数据包。

提出了PoR的证明,也就是中继证明。在中继证明中,在NKN网络中的每个客户端或节点都有公私钥对,密钥对可对交易进行签名。当数据包在NKN网络中传输时,节点用公私钥对数据包进行签名,同时把它中继到下个节点。下一个节点如此类推,这样形成了一条签名链。这意味着,攻击者是无法伪造签名链,除非它拥有所有路由节点的私钥。

NKN有两种方式获得代币奖励,一种是中继数据包的奖励,一种是挖矿奖励。所有运行NKN节点软件,并中继数据的节点都可以根据其贡献获得NKN代币奖励。这个中继数据服务的价格由发送方和接收方决定,也可以在所有参与中继数据的节点之间公平分配。挖矿奖励则是奖励给记账节点,它从中继节点中选出,记账节点提议新区块,如果新区块达成共识,那么该记账节点会被奖励挖矿代币。这个记账节点也是随机选择的,签名链是不可篡改,同时也是不可预测的,它的最后一个签名用于选择记账节点。

可扩展的摩卡共识 -MOCA

通过摩卡共识(MOCA),它根据节点自身的状态和邻居节点的状态来达成共识,它无须通过比较网络中的所有节点状态来达成共识。如果节点周围的邻居节点如果多数状态跟自己不同,节点会把自己的状态更改为多数状态并向邻居发送更新状态。通过邻居节点的相互作用和影响,最终在全网达成共识。

NKN网络中的节点类似于元胞自动机的细胞。每个节点都跟一定数量的邻居节点相连接,其网络共识的形成依赖于对其邻居节点状态做出的反应。它利用多数投票规则,实现可扩展的共识,其达成共识的时间随着系统规模扩展实现对数扩展。比如:N如果达到100万个节点数,它只消耗比现在50%多的资源。也就是说,NKN网络中有100万的对等节点,其消耗的带宽、CPU以及RAM资源仅比1万个对等节点的网络多50%。

1 Like