23 个版本
新 0.7.0-rc.1 | 2024 年 8 月 22 日 |
---|---|
0.6.1 | 2024 年 4 月 10 日 |
0.6.0 | 2023 年 11 月 1 日 |
0.5.0 | 2023 年 5 月 17 日 |
0.1.0 | 2021 年 11 月 2 日 |
#1691 在 网络编程 中
每月 22 次下载
用于 dusk-consensus
125KB
2.5K SLoC
Kadcast
根据 最新的论文版本(2021年) 实现的 Kadcast 网络层
覆盖构建
Kadcast 是一个基于 UDP 的点对点协议,其中节点形成一个结构化覆盖网络。
💡 规范建议该协议可以是无连接的,然而此实现使用了经典的 UDP。
所有节点在加入网络时都会生成一个唯一的 ID,该 ID 用作节点的唯一标识符。
💡 此实现使用从
端口> |
<ip_octects>
连接并截断为约定 16 字节的哈希生成的 128 位标识符。使用的哈希算法是Blake2
。
根据结构化网络的 Kademlia 规范,ID 确定了节点在二叉路由树中的位置。
每个节点维护一个路由状态集合,称为 k-buckets
,包含每个节点的位置。位置完全由元组 (ip_addr, port, ID)
确定。
每个桶包含最近看到的 K
个对等节点列表,这些节点位于与对等节点的给定距离处。距离是通过计算 non-euclidean XOR 距离度量
来确定的,它表示:d(x,y) = (x ^ y)
。
这意味着 i
个桶包含 K
个对等节点,其距离 d
符合以下公式:2^i <= d < 2^(i +1)
。
💡 因子
K
是一个全局参数,它决定了路由状态和查找复杂性。
-
如果桶的对等节点列表已满(即已有
k
个条目存储),则可以通过删除LRU
(最近最少使用)对等节点来插入该列表的新条目。 -
在从列表中删除条目之前,节点将检查要删除的对等节点是否仍然可达,通过发送
PING
消息并等待PONG
响应。如果在预定超时时间内未收集到PONG
,则检查失败,并且对等节点将从列表中删除。
💡 通过遵循
LRU
策略,该协议本质上倾向于网络中较老且更稳定的对等节点。
引导
当节点加入 Kadcast 网络时,它会从所谓的 bootstrap nodes
获取其他相邻对等节点的位置,以填充其桶。
💡 根据规范:当对等节点首次加入网络时,它必须知道至少一个引导节点的地址。因此,它向已知对等节点发送
PING
消息以检查它们是否实际上在线。此外,PING
将发送对等节点的路由信息传递给接收者,从而在其网络中分布其存在。
引导节点将回复包含其节点信息的 PONG
消息。
网络发现。
在引导过程之后开始。这一阶段的主要目标是使用 k-buckets
填充 k
个不同的对等节点。
- 该过程通过向已添加到
k-bucket
的引导节点发送FIND_NODE
消息来启动。 - 然后开始 查找过程。
- 节点通过在其自己的桶中查找关于 XOR 度量的 α 个最近对等节点来查找。
- 它通过发送
FIND_NODE
消息并等待NODES
响应来查询这些 α 个对等节点以获取其 ID。 - 查询的对等节点将响应一个包含它们认为最接近
ID
的k
个对等节点的NODES
响应。 - 根据获取的信息,节点构建一个新的最接近的对等节点集,并重复步骤 1 到 3,直到它不再获得比前一次迭代获得的更接近的对等节点。
⚠️ 注意,与桶大小类似,
𝛼
和k
也是全局常量,它们将确定网络的冗余和开销。典型值如下:k = [20, 100]
以及𝛼 = 3
。
定期网络维护
每个节点定期刷新每个无活动活动的桶。对于这样的每个桶,它选择一个适当的距离的随机 ID
,进行查找,并用新鲜的路由信息填充其桶。
提高广播可靠性和性能
我们不是将广播委托给每个桶的一个节点,而是选择 β
个委托。这是为了增加至少有一个诚实节点接收广播消息的概率。这是一项旨在帮助UDP协议固有的易失性,而不强制使用慢速CRC校验程序的措施。
由于每个广播过程在每个跳转(降低高度)上都会重复,因此节点必须忽略重复的 CHUNK
消息。此外,必须考虑传输失败。由于这些因素,此实现包括使用基于 RaptorQ 规范和相关 Rust 库 的前向纠错方案。可以通过参数 f = (n-s)/s
调整 FEC
额外开销因子。
如图表所示,即使在假设12%的数据包丢失率的情况下,我们也可以通过 β = 3
以及 f = 0,15
的情况下获得全网络覆盖(请参阅库文档中包含的基准测试)。
安全性
规范为DOS、Sybil和Eclipse攻击以及阻止区块交付提供了解决方案。在开发过程中已考虑到所有建议。
内部架构
有关内部架构的更多信息,请查看架构图。
依赖关系
~5–15MB
~166K SLoC