Python从头实现以太坊(五):类-Kademlia协议

Python从头实现以太坊系列索引:
一、Ping
二、Pinging引导节点
三、解码引导节点的响应
四、查找邻居节点
五、类-Kademlia协议
六、Routing

通过前面四个部分的介绍,我们了解了以太坊节点发现协议的一些基础知识,也实现了PingNodePongFindNeighborsNeighbors等数据结构,接下来我们就要开始具体深入的了解该协议的详细内容,包括节点距离计算,存储和查找等。本篇先介绍一些原理性的东西做个铺垫,对后续代码理解也有很大帮助。

分布式散列表(DHT)

如果让你编写一个 P2P 的聊天程序,你会怎么做?你可能首先想到的是,让每个客户端都到一台中央服务器先注册自己的信息(IP 地址和端口),我们称之为路由信息,这样,其中一个客户端要和目标建立 P2P 通讯的时候只要先连接到这台中央服务器询问一下对方信息就可以了。这种实现是最高效的,但是它的最大缺陷是这个中央服务器存在风险,比如被挟持篡改或断网下线。有什么办法可以绕过中央服务器找到目标信息?

广播,我把它称为找熟人。其中一个客户端先找自己“熟人”(已经连接的客户端)询问目标信息。“熟人”如果不知道目标信息,可以再找他们的“熟人”询问,一级一级找下去,最终一定也能找到目标。这种实现虽然绕过了中央服务器,但是却效率低下,还有可能会引起“广播风暴”或者“泛洪”,对整个系统是一个灾难。

那么有没有一种办法既可以绕过中央服务器又可以避免“广播”的弊端呢?

这个时候就该 DHT 粉墨登场了。它结合了前面的两种思路,把中央服务器的路由信息分成许多份,分布存储在每个客户端上,查找的时候先在本地路由信息里面查找,没有的话再选一个路由询问,直至找到目标。这是我对 DHT 的通俗解释,实际操作上要复杂得多,它的协议实现也是五花八门,我现在要讲的就是其中比较流行的一种——Kademlia

Kademlia协议

Kademlia 是一种基于距离算法的 DHT,这个“距离”并不是地理意义的距离,而是算术意义上的,它以异或运算作为计算距离的依据。异或运算我们见得比较多的是用在对称密码学里面,比如著名的 One Time Pad,因为它有一个特性是:sec ^ key = enc(加密); enc ^ key = sec(解密)。

还有很多独特的性质,使得它在算术和节点树上具有实际意义。一个对象我们用一个唯一的二进制的 ID 来表示,那么 ID 间异或运算反映的就是 ID 中比特的差异情况,也可以说是对象的差异,因为这里的 ID 就是对象的基因,基因差异不就是个体差异嘛,而且越靠前(高位)的比特对最终的差异结果影响的权值越大。如果把这样的 ID 统统竖起来,高位比特朝上,低位比特朝下,同一分支下比特一样的束在一起,我们就可以得到一棵二叉树,这时候,这种差异值就体现了这棵树的叶子(树枝末端)之间的相邻距离。


5位比特的数字 ID

Kademlia 中使用的是160 位比特的数字作为节点 ID,这个数字空间可以达到 2¹⁶⁰,整颗树太庞大了,电脑是无法存储的。所以我们只能按一定规则将这棵大树拆分成许多小树,分别存储在各个节点上,用于路由查询。具体拆法就是对这颗树的各比特位 i160>i≥0),每一个节点只存储不超过 k 个与自己相距在 [2^i, 2^(i+1)) 范围内的节点信息(ID,IP 地址和端口),我们把它叫做 k-桶。k-桶实际上就是节点的路由表。

k-桶的生成过程如图所示:


5位比特的 ID,k 为2的情况下,节点 C 生成路由表的过程

总的来说,一开始只有一个 k-桶,它包含了整个 ID 数字空间。当我们探测到一个节点的时候,我们计算一下跟自己的距离然后把它加到现有的相应的 k-桶中,如果:

  • k-桶没满,把它加到 k-桶末尾。
  • k-桶满了,如果:
    • k-桶包含节点自己,这个k-桶向下(节点树枝方向)一分为二,直到不可再分为止(即 i=0)。
    • k-桶不包含节点自己,取出最早插入的节点重新 PingNode,没有响应的话就把它删除掉,新的节点加到 k-桶末尾。

Kademlia 尽量多地储存“离自己更近的节点”的路由设计保证查询最终是收敛的。

以太坊的“类-Kademlia”协议

以太坊的节点发现和网络结构并没有严格按照 Kademlia 协议实现,它是一种 类-Kademlia 的协议,顾名思义就是类似但不尽相同。它们之间主要区别在于:

  • Kademlia 定义了四种操作:

    • PING:探测一个节点是否在线
    • STORE:令对方储存一份数据
    • FIND NODE:根据节点 ID 查找一个节点
    • FIND VALUE:根据键查找一个值(数据)

    但 类-Kademlia 里面并不需要FIND VALUESTORE数据包结构。

  • 类-Kademlia 里面数据包是经过签名的。

  • 类-Kademlia 节点直接拿它的公钥(256位比特)作为其 ID。

  • 参数的不同:

    • 行(跟 k-桶类似)大小是16(即 Kademlia 的k参数)
    • FindNeighbors并发数是3(即 Kademlia 的alpha参数)
    • 路由每跳8位比特(即 Kademlia 的b参数)
    • PingNodeFindNeighbors请求超时时间是300ms(这里指的是一个来回的时间,从发出 PingNode 到返回对应的 Pong,从发出 FindNeighbors 到返回Neighbors的时间)
    • k-桶空闲刷新间隔是3600s(所谓空闲就是一个k-桶已经有相当一段时间没有发生任何节点增加或驱逐的变化了)

怎么理解这些参数呢,在 Kademlia Peer Selection 有说到,类-Kademlia 中的路由表由行组成,一开始是1行,最多可以到255行。每一行包含 k 个节点信息,k 设定大小决定了网络的冗余程度。如果某一行包含的节点 ID 具有相同的比特前缀位数是 i 的话,我们就把这一行标号为 i。这里的 i 和 Kademlia 论文提到的 i 是不一样的,Kademlia 论文中的 i 值越高,表示异或距离越大,而这里的 i 值越高,表示具有相同比特前缀的位数越多。当行满的时候,如果这行包含自身节点或它的行号不是 b 的整数倍,它就分裂成两行,否则它就只做一些节点更新替换。我们把这个 b 形象地称为“路由每跳比特位数”。

类-Kademlia 当 b=2 时路由表生成过程

理论部分介绍到这,下一次我们就要开始编写节点路由表了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容