风险提示:理性看待区块链,提高风险意识!
引介 | 使用覆盖层改变以太坊状态树的格式
首页 > 币界资讯 > 矿业前瞻 2020-04-17 11:16:31

账户和合约存储数据的方式是影响以太坊的众多问题之一。以太坊协议选用了 Merkle Patricia Tree(MPT,默克尔帕特里夏树)来组织账户及合约数据。尽管这种数据结构在理论上效果很好,但在实际应用中,它带来的问题却比它能够解决的问题多。核心开发者们已经讨论多年,想要把这种数据结构换为二叉树,我将在这篇文章中阐述我对这个问题的看法以及如何实现这种转变。

我所提议的处理方法包括一段时间的过渡期,在这段时间内,网络要同时维护两种树结构。这样做的好处是,转换树结构的过程不会影响链的运行,并且可以确保所有的账户都被转换成了二进制格式。

背景

目前,以太坊的状态树是十六叉制的。十六叉制表示每个节点有 16 个孩子节点。理论上讲,这种方式挺好的,因为孩子节点多意味着只需要更少的 “层” (即树高)便可存储所有数据。

例如,下图是用十六叉树表示的键值对 (170, v)。十六进制中,170 记作 0xaa,因此你只需要两层:第一层记录第一个a,第二层记录第二个a。

- 图 1. 十六叉树的例子,展示了值 v 是如何在在对应键 0xaa 处是存储的。这棵树的键长度只有 2 个字节,只有沿着 0xaa 的子树被表现出来了。为了简洁,不相关的子树替换为 “...” -

可以看出,上图的树很矮,而且很宽。给定相同的键值对,下图展示了二叉树存储的情形。170 在二叉树中被表示为 10101010。

- 图 2. 与图 1 相同的键值对,存储在二叉树中。为了简洁,不相关的子树被表示为“...” -

从图中可见,二叉树要深得多,也窄得多。

以太坊中,每个区块包含一个 stateRoot 字段,这是该块处理完成后表示以太坊全局状态的 MPT 的树根哈希值。总的来说,这个哈希值是对根节点的 16 个孩子节点的哈希值所组成的列表作哈希运算得到的。这些孩子节点的哈希值又是孩子的 16 个孩子节点的哈希值所组成的列表做哈希运算得到的,以此类推。

每次打包交易生成新区块时,矿工都会更新账户树,重新计算根哈希。根哈希存储在新区块的 stateRoot 字段,然后新区块被共识。

- 图 3. 区块头中的状态根字段,指向十六叉树的树根 -

问题在于:如果要对所有节点做哈希,重新计算根哈希的时间就太长了,因此,为了计算根节点的哈希,矿工将从数据库中检索同层节点的兄弟哈希值sibling hashes) 。虽然后者(矿工从数据库检索兄弟哈希值)花费的时间没有前者(矿工从数据库库得到所有的叶子节点并做哈希)那么多,这个操作还是很耗时。因为每个哈希都必须从数据库中取出。

在十六叉树中,通常每一层你都需要取出 15 个兄弟哈希值。在上面那个我构造的例子(图 1)中,(重计算根哈希)就需要 30 个哈希值。

尽管二叉树层次更深一点,但在每一层只需要一个兄弟哈希值。在上述例子(图 2)中,仅仅需要 8 个哈希值!这就是为什么在实际中二叉树更优。

覆盖层转变方法

不幸的是,转换为二叉树并不简单。需要转换的数据太多了,执行转换花费的时间将多于 15 秒的区块生成时间 。

除此以外,设想你要翻译一本 5000 页的书,作者还在不停地告诉你他们对故事做了些修改,并且这些修改会影响你已经翻译过的页 …… 那这个过程就没完没了。转换状态树的格式也是一样的问题:可能你刚完成某个地址的格式转换,用户就使用了该地址(因此更新了该地址的状态),那你又得从头转换一遍(因为一个地址的状态更新也会影响到整棵状态树)。

解决这个问题的办法是增加一个过渡期,过渡期间,在十六叉树基层上建立一棵覆盖树(overlay tree)。这棵覆盖树是二叉树格式的,它的作用是保存状态上发生的所有变化,直到基十六叉树完全转换为二叉树。转换分为 3 步进行。

第 1 步 —— 转换

在这种方法下,区块高度为H1时肯定会有两个状态根:一个是 “基层” 十六叉树状态根,一个是 “覆盖层” 二叉树状态根。

- 图 4. 转换过程中,区块拥有两个状态根:一个是传统十六叉树的只读根,一个是覆盖二叉树的可读写根 -

十六叉树被设置为只读,因此对状态的任何更新都将在覆盖树上进行。

当一笔交易读取或者更新一个账户时,系统首先会搜索覆盖树。如果在覆盖树中找不到账户,接着将会在旧的十六叉树中搜索值。

与此同时,十六叉树在后台进行转换。此时不需要担心值插入的问题,因为所有的改变都会存储在上层的覆盖树中。

第 2 步 —— 基层树切换

当后台转换过程完成,矿工对外宣告,他们已经准备好用转换结果(只读二叉树根)来替换只读的十六进制基层树根。对状态的读写与步骤 1 阶段是一样的。(译者注:此时的只读二叉基层树是根据原本的十六进制状态树得到的)

- 图 5. 转换的第二个阶段,矿工在区块头使用转换所得二叉树的树根替换十六叉树根,向网络示意他们已经准备好了 -

当足够多的一系列区块对转换所得的二叉基层树根给出了相同的值,意味着大多数矿工都完成了转换,并且认可转换后的树。合并过程则开始。(译者注:此时的合并是针对只读二叉基层树和可读写二叉覆盖树)

第 3 步 —— 合并两棵树

合并过程不断推进:每产生一个新的区块,就从覆盖树上删除 n 个键,把它们重新插入二叉基层树。此过程一直持续,直到所有的键都从覆盖树上移除。到达这步时,区块头就不再保留覆盖状态树的树根。

整个步骤的核心只有一个:如果交易执行时要写的键存在于覆盖树上,这个键就会从覆盖树上删除,写操作直接在二叉基层树上进行。

下一步

为了估计完成转换所需要的时间,我已经做了一个低转换率的原型系统。我们确信,整个过程花费的时间不会太离谱,也就是说几天时间就够了。我们会随着算法的改进而公布更多细节。

致谢

此提议得益于 Alexey Akhunov、Vitalik Buterin、Anna George、Sina Mahmoodi、Tomasz Stanczak 以及 Martin H. Swende 的宝贵意见。

(完)

原文链接:https://medium.com/@gballet/ethereum-state-tree-format-change-using-an-overlay-e0862d1bf201作者:Guillaume Ballet翻译&校对:裴奇 & 阿剑

上一篇: 什么是轻客户端?为什么你需要了解它?
下一篇: 以太坊合约交互中的“授权”究竟是什么?
推荐专栏
web3首席知识博主
一位相信价值投资的币圈KOL。稳定盈利的缠论野生交易员 #BTC行情分析师 #价值投资 #链上数据分析
爱Web 3,爱生活,爱科技,爱炒币的老韭菜
热门币种
更多
币种
价格
24H涨跌幅
BTC比特币
¥272,519.10
38,183.45 USDT
+3.04%
ETH以太坊
¥14,715.70
2,061.86 USDT
+2.3%
USDT泰达币
¥7.19
1.01 USDT
-0.11%
BNB币安币
¥1,642.10
230.08 USDT
+1%
XRP瑞波币
¥4.37
0.61160 USDT
+0.72%
USDC
¥7.13
0.99960 USDT
-0.05%
SOLSolana
¥436.70
61.19 USDT
+10.1%
ADA艾达币
¥2.75
0.38600 USDT
+3.46%
OKBOK币
¥407.51
57.10 USDT
+2.43%
DOGE狗狗币
¥0.57240
0.08020 USDT
+3.97%
热搜币种
更多
币种
价格
24H涨跌幅
Terra Classic
¥0.00
0.00012023 USDT
+27.59%
Gala
¥0.19
0.026355 USDT
+3.84%
比特股
¥0.04
0.006206 USDT
-5.6%
dYdX
¥22.57
3.1906 USDT
+0.22%
FTX Token
¥28.54
4.0337 USDT
-1.45%
Filecoin
¥32.25
4.5589 USDT
+2.72%
PancakeSwap
¥15.80
2.2339 USDT
+2.34%
比特币
¥270,140.27
38183.45 USDT
+3.04%
Yield Guild Games
¥2.66
0.3756 USDT
+4.28%
Shiba Inu
¥0.00
8.34E-6 USDT
+2.71%
Conflux
¥1.09
0.1541 USDT
+1.78%
柚子
¥4.82
0.6814 USDT
+1.67%
最新快讯
更多
HashKeyExchange将于11月30日上线DOT/USD
2023-11-29 18:15:51
经合组织:预计美联储不会在2024年下半年之前降息
2023-11-29 18:09:37
一新钱包从Binance收到6.98亿TVK,占总供应量的58.18%
2023-11-29 18:05:47
Nym计划年底推出NymSwapper,支持ERC-20代币兑换为原生NYM
2023-11-29 18:00:49
蜜蜂查24小时行情晚报(11-2918:00)
2023-11-29 18:00:00
BC科技集团股价单日涨幅达47.11%,暂报9.93港元
2023-11-29 17:52:21
BC科技集团股价单日涨幅达47.111%,暂报9.93港元
2023-11-29 17:52:21
下载币界网APP