Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

二叉状态树的结构

有个胖子他姓杨
188 0 0
    在设计十六进制trie时,一些设计选择在当时听起来很棒,但是经过5年的实践,被证明带来了很多复杂性。鉴于ETH1.x想要转向二进制trie,我们正好可以借此机会研究一下状态的存储方式。" Q5 `9 L$ W4 n6 N

. c' l# Y1 E7 o% r8 q    问题的根源
( L+ r1 R# t* W0 H! t1 \0 n

! J9 `9 g  R/ z! e    在重新设计存储格式时,我们至少可以从5个方面进行改进。0 E  B& ~( E6 M5 ]
3 ^9 T9 {! x, V4 a: z
    将账户trie和存储trie合并:维护多个结构会增加复杂性,典型的例子就是节点必须先遍历账户5 f3 G% @0 @0 p

1 v8 i: k8 w! J" r! c9 W    trie,得到存储trie的根,然后再到存储trie上获取数据。
6 N! @$ b1 i  X0 ^
) p2 b2 [. v) D$ H, I  h3 ~6 r# |( f) C    扩展节点(extensionnodes):这是一种特殊的节点,负责给特定子树上的所有key加上前缀。这些节点的作用是能够限制需要被哈希的节点数量,但是也引入了复杂性,因为它们所涉及的key必须以特定方式打包。* V# l9 q7 i0 i- ^" B

4 p# s2 G* G8 @" F: \' q    RLP编码格式旨在高效地对任意结构进行编码。由于其复杂性,它也带来了很多麻烦:必须费尽千辛万苦打包key块(packkeychunk)。另外,由于每个节点的结构相当固定,可以使用更简单的序列化方法来代替RLP。' n9 `  X4 ^  b) {5 M, @( d
2 x' B/ j0 N. p& z% _, a: p
    与前两个问题相关的是,十六进制的前缀也会带来复杂性和混乱。
9 z& g1 z. r6 N4 e
& e8 T$ K2 U' U: N; v7 a) ]    十六进制trie的证明【即,“见证数据(witness)”】比二进制trie的证明大4倍左右。(欲知详情,请阅读这篇文章。(中文译本)): w: |: h4 `# L# O* q
; s" n/ D' O7 [9 b' c1 f: x
    RLP2 Z0 ^/ h4 [3 N5 F. ]
2 Q4 B" V) k: H) y/ C3 _4 g
    ——Ramble,LoseyourselfandPester?3 }% @0 S, o3 N. v. ?6 O

! b& Z4 z/ ^7 Q9 u    (译者注:“RLP”是“RecursiveLengthPrefix(递归长度前缀)”的缩写,但作者这里使用了几个R、L、P开头的词“漫无目的、迷失自我、喋喋不休”,就是批评之意。)本文我们会讨论怎么解决RLP问题。如果RLP被取代,绝大多数核心开发者都不会感到伤心。这是因为RLP过于复杂。实际上,我听过的唯一一个支持保留RLP的理由是:“RLP实在太过复杂,不要再冒险选择新的格式了,以免重蹈覆辙。”RLP. a. a/ L: ?* Y; |& z; p

! [! ?  o# z9 P. g/ [/ d  m6 S    的基本原理是采用简单的size+data格式。这就是复杂性的由来。首先,size可以是任何整数(实际上,它不可能超过2字节,但是从原则上来说是可以的,因此你必须确保能够支持超过2
$ f7 D0 @  |: e5 r1 R6 z# F% N* a- R% o( [4 d0 h6 I0 y
    字节的size)。我们如何知道size部分在哪里结束,data部分在哪里开始?
& \; k8 u$ w2 j( l8 M( U" Z% k4 s
, B: S; [0 S& R, o    在大多数情况下,开头会加上一个header。这个1 j1 Z, }- E2 R
4 H) |3 e* M- S" m. p
    header是一个值h,然后再加上size值:因此,RLP编码是[length(data)+h][data]! g, |4 J: i; f3 r# x+ J
- B& W3 W) y* N; d  h8 [4 M
    如果length(data)+h
) J$ m* Z0 [+ j1 p1 P2 @& }
  Y7 k% P: {/ }9 P    如果数据大小为一个字节,你发现自己必须在这个字节前再增加一个字节。有没有可能不这样做?部分情况下可以,但是会另外增加复杂程度!如果data[0]- x7 {% Y# P" Z; t$ F
% n. B% O6 p* Z. y2 M# g
    还能再酸爽一点吗?当然可以了!RLP涉及两类“对象”:结构列表和字节数组。
0 `4 j, s' K  G" b; x0 T. a$ M; Z: ^
    字节数组:header=128,overflow_header=183% L% U/ Q5 N! j7 l& \% r

$ {- O0 B+ X) s1 R4 q% h    结构列表:header=192,overflow_header=247" A& u( M+ J' F; D- L

8 K: n- L1 b: u- j9 w5 Q* U# n    请注意,datasize部分的最大规模是8bytes,也就是一个
( h( a& U7 J) ?+ l5 h5 L
$ p4 |) v; Q4 l9 t2 x    64bits(原文为“64-bytes”,应有误)的数字。确实,无论什么数据,18014398509481984KB应该都够用了。虽然还有很多棘手的细节有待深入,但要点看起来很清楚了:RLP难以驯服。我们再来看看它是如何与状态树交织在一起的。$ f+ q& q1 k4 V- N# g
! b1 N; X+ Y- |" U+ [* p
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    0

  • 主题

    10