Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

二叉状态树的结构

有个胖子他姓杨
133 0 0
    在设计十六进制trie时,一些设计选择在当时听起来很棒,但是经过5年的实践,被证明带来了很多复杂性。鉴于ETH1.x想要转向二进制trie,我们正好可以借此机会研究一下状态的存储方式。! k. c! i, R7 T' s! C) b/ w# s
; p, ]% W- Z6 a7 {5 W4 i
    问题的根源5 i) O" r' j  u. a/ `* f% f
. c8 j$ |# }$ U0 V
    在重新设计存储格式时,我们至少可以从5个方面进行改进。# B) V+ {* `  ]! {  m

  N$ c. ~; S. h2 L0 p0 W    将账户trie和存储trie合并:维护多个结构会增加复杂性,典型的例子就是节点必须先遍历账户) N2 N- e+ Y: ~/ [
; v+ J7 f8 A: D/ X! }' o
    trie,得到存储trie的根,然后再到存储trie上获取数据。
. @" O0 s( D5 c+ ^. z. f. k0 w7 j* i4 }+ d
    扩展节点(extensionnodes):这是一种特殊的节点,负责给特定子树上的所有key加上前缀。这些节点的作用是能够限制需要被哈希的节点数量,但是也引入了复杂性,因为它们所涉及的key必须以特定方式打包。
/ f4 A5 n) U+ {6 Z% \
/ ^+ T4 a2 x; N1 k% S/ f, ]    RLP编码格式旨在高效地对任意结构进行编码。由于其复杂性,它也带来了很多麻烦:必须费尽千辛万苦打包key块(packkeychunk)。另外,由于每个节点的结构相当固定,可以使用更简单的序列化方法来代替RLP。7 Y. J7 N% c1 {) R0 n

0 E2 k1 V% W/ {; c0 l+ K    与前两个问题相关的是,十六进制的前缀也会带来复杂性和混乱。! p: e" U+ c7 L- J5 J& _; w
( S" @8 w4 u- K& c$ h
    十六进制trie的证明【即,“见证数据(witness)”】比二进制trie的证明大4倍左右。(欲知详情,请阅读这篇文章。(中文译本))
3 \: T+ J. L4 U! Y* @% q0 k
3 A9 Y4 r0 c+ b8 p& a3 z    RLP& V& U% n7 s( t2 j& @- P4 x
9 n( o# C$ G# Q
    ——Ramble,LoseyourselfandPester?
$ x5 P9 Q* d8 i4 A
9 h8 j' \/ i+ n  n5 R    (译者注:“RLP”是“RecursiveLengthPrefix(递归长度前缀)”的缩写,但作者这里使用了几个R、L、P开头的词“漫无目的、迷失自我、喋喋不休”,就是批评之意。)本文我们会讨论怎么解决RLP问题。如果RLP被取代,绝大多数核心开发者都不会感到伤心。这是因为RLP过于复杂。实际上,我听过的唯一一个支持保留RLP的理由是:“RLP实在太过复杂,不要再冒险选择新的格式了,以免重蹈覆辙。”RLP# f' |" ~3 b/ {/ h

+ Q# q7 O8 e# a    的基本原理是采用简单的size+data格式。这就是复杂性的由来。首先,size可以是任何整数(实际上,它不可能超过2字节,但是从原则上来说是可以的,因此你必须确保能够支持超过2. S) p, D2 m: t, h
- V1 W4 A1 s& i/ [8 j) f
    字节的size)。我们如何知道size部分在哪里结束,data部分在哪里开始?
$ ~& |7 x. F0 x+ O' h1 O9 ?+ ]$ N/ |4 A( N& w  ?8 K
    在大多数情况下,开头会加上一个header。这个
. [7 _+ ~! L0 D4 r' |
1 k1 A: s6 V% h0 J+ ^0 h7 s. g( Y    header是一个值h,然后再加上size值:因此,RLP编码是[length(data)+h][data]
8 w* D1 {( c8 R- [8 ?7 j+ j: Y1 P, J( V' ^) U9 ~) ^
    如果length(data)+h3 k+ w, D0 N# X- u8 L( h( p

$ S: g* S. j/ [5 _8 f$ V    如果数据大小为一个字节,你发现自己必须在这个字节前再增加一个字节。有没有可能不这样做?部分情况下可以,但是会另外增加复杂程度!如果data[0]% T$ S+ h. q. v/ A& _) R* q

" Y. _* X7 l8 c6 K9 b% z/ f: n    还能再酸爽一点吗?当然可以了!RLP涉及两类“对象”:结构列表和字节数组。( I; [; y6 j4 y  D! l1 [: _

/ Z2 k/ }! N* `6 T6 {8 [    字节数组:header=128,overflow_header=183+ z, K5 o& ?: |3 V8 q
7 W/ Q" Y+ w, S6 i0 h$ d
    结构列表:header=192,overflow_header=247, {$ o0 K: G. U9 n
1 {. h1 ]7 e$ d0 z2 J) ~9 U
    请注意,datasize部分的最大规模是8bytes,也就是一个1 e2 I+ ~( j( x+ r1 H4 Q- p: D1 c

* v( h2 I& H1 Q) E; Q0 I    64bits(原文为“64-bytes”,应有误)的数字。确实,无论什么数据,18014398509481984KB应该都够用了。虽然还有很多棘手的细节有待深入,但要点看起来很清楚了:RLP难以驯服。我们再来看看它是如何与状态树交织在一起的。4 H2 f, ]. W! P

8 U& T! a1 t& @2 B
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    0

  • 主题

    10