Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

二叉状态树的结构

有个胖子他姓杨
150 0 0
    在设计十六进制trie时,一些设计选择在当时听起来很棒,但是经过5年的实践,被证明带来了很多复杂性。鉴于ETH1.x想要转向二进制trie,我们正好可以借此机会研究一下状态的存储方式。
9 _9 k6 J; A! H! J8 k+ C
( t- z5 P$ G, n& K; K    问题的根源
5 Y% U7 S: x% B. r7 M1 [

6 M( i* d$ D, C* ~1 w+ D+ |    在重新设计存储格式时,我们至少可以从5个方面进行改进。
* d% e8 M  h5 v2 A* X6 J$ v$ S  M4 ~$ q, T5 U  u/ U
    将账户trie和存储trie合并:维护多个结构会增加复杂性,典型的例子就是节点必须先遍历账户
- K4 S8 c8 G/ K
+ e4 `6 _1 n: R9 h! F" m* y( [3 {    trie,得到存储trie的根,然后再到存储trie上获取数据。
4 }. v$ i6 m  V! g4 i  J* @- S/ E: a$ T
    扩展节点(extensionnodes):这是一种特殊的节点,负责给特定子树上的所有key加上前缀。这些节点的作用是能够限制需要被哈希的节点数量,但是也引入了复杂性,因为它们所涉及的key必须以特定方式打包。( I: s; G3 J% i6 f/ d; O0 z
# e" w, v/ v6 U4 ]: d
    RLP编码格式旨在高效地对任意结构进行编码。由于其复杂性,它也带来了很多麻烦:必须费尽千辛万苦打包key块(packkeychunk)。另外,由于每个节点的结构相当固定,可以使用更简单的序列化方法来代替RLP。+ V( \4 @5 o- ]2 I2 d/ G5 V( I9 {

: Z; n: V& m3 a0 b! q( r    与前两个问题相关的是,十六进制的前缀也会带来复杂性和混乱。
% `  g: Z8 D3 x& ]% A  J" h+ s% Z. x  h3 l4 }9 H
    十六进制trie的证明【即,“见证数据(witness)”】比二进制trie的证明大4倍左右。(欲知详情,请阅读这篇文章。(中文译本))5 ?& N5 b4 f7 j+ q) Y
4 c5 Y) K4 X- X2 |9 f! q
    RLP3 t' R2 P9 s& J+ u
5 N1 T' X$ O  V' I' A. V
    ——Ramble,LoseyourselfandPester?7 L7 d( H# o/ q( B: l6 ?% H
2 U$ K) ^9 i& i$ U' M
    (译者注:“RLP”是“RecursiveLengthPrefix(递归长度前缀)”的缩写,但作者这里使用了几个R、L、P开头的词“漫无目的、迷失自我、喋喋不休”,就是批评之意。)本文我们会讨论怎么解决RLP问题。如果RLP被取代,绝大多数核心开发者都不会感到伤心。这是因为RLP过于复杂。实际上,我听过的唯一一个支持保留RLP的理由是:“RLP实在太过复杂,不要再冒险选择新的格式了,以免重蹈覆辙。”RLP0 p# v8 K! m2 ?/ g. [4 y

8 u5 C0 q" Z( {    的基本原理是采用简单的size+data格式。这就是复杂性的由来。首先,size可以是任何整数(实际上,它不可能超过2字节,但是从原则上来说是可以的,因此你必须确保能够支持超过22 @+ W) j& ^. L; I/ d9 s) t

8 @& P  ^: @/ K    字节的size)。我们如何知道size部分在哪里结束,data部分在哪里开始?* B% h' I) I0 R+ q. c4 w
; y4 n$ q' u: O
    在大多数情况下,开头会加上一个header。这个
) C  i! j, M7 D5 Y; a  m3 D( K5 P, o9 H* x1 {
    header是一个值h,然后再加上size值:因此,RLP编码是[length(data)+h][data]: e8 |  V$ P* T

' v% u+ a: x, G7 }5 S3 }6 f    如果length(data)+h
) \: C- H3 {$ V8 D1 }
) T5 B" g0 {, ?* Y7 c    如果数据大小为一个字节,你发现自己必须在这个字节前再增加一个字节。有没有可能不这样做?部分情况下可以,但是会另外增加复杂程度!如果data[0]
0 p& I  n* M8 J/ I1 `1 K
2 p$ k; S1 F' }1 F, B+ T( r: G' K    还能再酸爽一点吗?当然可以了!RLP涉及两类“对象”:结构列表和字节数组。" ]1 B: Z( T. O6 J' p

( ]# B$ P+ b( g    字节数组:header=128,overflow_header=183" b& `, b+ _: j2 _
" f  `8 C+ M# c' H
    结构列表:header=192,overflow_header=247' c2 E: j+ B% n9 k
( a9 U) G# n5 n+ s% R- b! O9 f1 ^
    请注意,datasize部分的最大规模是8bytes,也就是一个! l+ q2 n% v# M, n
0 s  X! @- w  B8 y# z. P$ f
    64bits(原文为“64-bytes”,应有误)的数字。确实,无论什么数据,18014398509481984KB应该都够用了。虽然还有很多棘手的细节有待深入,但要点看起来很清楚了:RLP难以驯服。我们再来看看它是如何与状态树交织在一起的。
! T8 C& G$ [, f) p5 T
$ f# V8 s3 q4 f( q+ K
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

有个胖子他姓杨 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    10