问题的根源
在重新设计存储格式时,我们至少可以从5个方面进行改进。
将账户trie和存储trie合并:维护多个结构会增加复杂性,典型的例子就是节点必须先遍历账户
trie,得到存储trie的根,然后再到存储trie上获取数据。
扩展节点(extensionnodes):这是一种特殊的节点,负责给特定子树上的所有key加上前缀。这些节点的作用是能够限制需要被哈希的节点数量,但是也引入了复杂性,因为它们所涉及的key必须以特定方式打包。
RLP编码格式旨在高效地对任意结构进行编码。由于其复杂性,它也带来了很多麻烦:必须费尽千辛万苦打包key块(packkeychunk)。另外,由于每个节点的结构相当固定,可以使用更简单的序列化方法来代替RLP。
与前两个问题相关的是,十六进制的前缀也会带来复杂性和混乱。
十六进制trie的证明【即,“见证数据(witness)”】比二进制trie的证明大4倍左右。(欲知详情,请阅读这篇文章。(中文译本))
RLP
——Ramble,LoseyourselfandPester?
(译者注:“RLP”是“RecursiveLengthPrefix(递归长度前缀)”的缩写,但作者这里使用了几个R、L、P开头的词“漫无目的、迷失自我、喋喋不休”,就是批评之意。)本文我们会讨论怎么解决RLP问题。如果RLP被取代,绝大多数核心开发者都不会感到伤心。这是因为RLP过于复杂。实际上,我听过的唯一一个支持保留RLP的理由是:“RLP实在太过复杂,不要再冒险选择新的格式了,以免重蹈覆辙。”RLP
的基本原理是采用简单的size+data格式。这就是复杂性的由来。首先,size可以是任何整数(实际上,它不可能超过2字节,但是从原则上来说是可以的,因此你必须确保能够支持超过2
字节的size)。我们如何知道size部分在哪里结束,data部分在哪里开始?
在大多数情况下,开头会加上一个header。这个
header是一个值h,然后再加上size值:因此,RLP编码是[length(data)+h][data]
如果length(data)+h
如果数据大小为一个字节,你发现自己必须在这个字节前再增加一个字节。有没有可能不这样做?部分情况下可以,但是会另外增加复杂程度!如果data[0]
还能再酸爽一点吗?当然可以了!RLP涉及两类“对象”:结构列表和字节数组。
字节数组:header=128,overflow_header=183
结构列表:header=192,overflow_header=247
请注意,datasize部分的最大规模是8bytes,也就是一个
64bits(原文为“64-bytes”,应有误)的数字。确实,无论什么数据,18014398509481984KB应该都够用了。虽然还有很多棘手的细节有待深入,但要点看起来很清楚了:RLP难以驯服。我们再来看看它是如何与状态树交织在一起的。
BitMere.com is Information release platform,just provides information storage space services.
The opinions expressed are solely those of the author,Does not constitute advice, please treat with caution.
The opinions expressed are solely those of the author,Does not constitute advice, please treat with caution.
Write the first review