geth访问节点_干货 | 了解 Geth 客户端:快照加速机制

本文探讨了以太坊 Geth 客户端在处理状态访问时面临的挑战,尤其是硬盘读写放大的问题。通过介绍默克尔帕特里夏树的原理,阐述了数据存储和验证的复杂性。文章提出,并非所有状态访问都需要同等处理,区分不同场景可以优化性能。同时,讨论了快照加速机制,包括内存缓存、布隆过滤器等优化手段,以减轻硬盘访问压力。
摘要由CSDN通过智能技术生成

本文为 Geth 客户端有问必答系列的第一篇文章,大家可以就 Geth 客户端的问题踊跃提问,我会每周用一篇小文章回答得票最高的问题。本周呼声最高的问题是:你能说说 flat 数据库结构与 legacy 结构的主要区别吗?

以太坊的状态

在深入了解加速结构(acceleration structure)之前,我们先回顾一下以太坊的 “状态” 概念、状态在涉及到不同层次的抽象时又是如何存储的。

以太坊有两种不同类型的状态:账户的集合;每一合约账户存储槽的集合。从 完全抽象的角度 来看,两种数据都是 键-值 对。账户集合把地址映射到该地址的 nonce、余额,等等。而一个合约的存储领域把任意的值(由该合约定义并使用)映射到某个值。

但糟糕的是,虽然把这些键值对存储成扁平数据(flat data)可以非常高效,但验证它们的正确性在计算上就会变得很难。每当对数据修改时,我们都要自下而上对所有数据做哈希运算。

为免去总是对整个数据库做哈希运算的需要,我们可以把数据库分割成连续的小片,然后建立出一种树状结构!最原始、最有用的数据就放在叶子节点上,然后树上每一个内部节点都是该节点以下内容的哈希值。如此一来,当我们要修改某些值时,就只需做对数次的哈希运算。这种数据结构其实有一个路人皆知的名字,就是 “默克尔树”。

但还没完,这种办法在计算复杂性上还是有所欠缺。默克尔树结构虽然在修改现有数据时非常高效,但是,如果插入数据和删除数据会更改底层小数据块的边界,那就会让所有已经算好的哈希值全都变为无效。

这时候,与其盲目地对数据库分组,我们可以使用键本身来组织数据、基于共同前缀将数据都安排到树状格式中!这样插入和删除操作都不会影响到所有节点,只会影响到从树根到叶子路径上的(对数个)节点。这种数据结构就叫 “帕特里夏树”。

把上面两种办法合在一起 —— 帕特里夏树的树状分层和默克尔树的哈希算法 —— 就是所谓的 “默克尔-帕特里夏树”,也是实践中用于代表以太坊状态的数据结构。无论是修改、插入、删除还是验证,都只有对数复杂度!唯一的小小例外是,有些键会在插入前做哈希运算(存入树中),以平衡整棵树(A tiny extra is that keys are hashed before insertion to balance the tries)

以太坊的状态存储

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值