本文深入探讨了以太坊中“无状态性”的概念及其在解决状态增长问题中的作用。文章分析了完全无状态和部分无状态两种方案,以及在弱无状态和强无状态协议中,区块生产者应如何存储状态。文章还探讨了状态增长对gas限制的影响,以及未来以太坊协议设计中,状态增长与proof-serving节点架构之间的权衡。
_感谢 Guillaume Ballet, Ignacio Hagopian, CPerezz, Barnabé Monnot, Caspar Schwarz-Schilling, Thomas Thiery, Kev, Dankrad Feist, Justin Drake, and Ng Wei Han._
以太坊中的状态(State)是包含所有账户余额、账户 nonce、合约字节码和合约存储的数据。随着新的账户和合约被添加到以太坊以及现有合约写入更多存储,状态也在增长。验证者执行的一个关键角色是证明(attesting):发布投票,表明一个区块是否有效并应被最终确认。庞大的状态大小是有问题的,因为不能期望证明者存储过多的数据,并且状态访问在计算上变得更加昂贵。当前的以太坊协议需要证明者存储状态,因为没有它,证明者无法独立执行其核心职责:验证区块是否有效。
社区希望以太坊得到更广泛的使用,因此状态将会增长。然而,他们不希望状态增长给证明者带来负担,因为更高的证明者硬件要求会降低网络的质量。无状态性(Statelessness)是被提议的解决方案空间,允许状态增长,同时确保证明者不需要过于昂贵的硬件。已经讨论了无状态性设计空间内的各种解决方案。
人们花费了大量精力来消除证明者存储(完整)状态的需求。然而,相对较少的人关注谁应该持有状态。本文的目的是探讨应该由谁来持有状态,而不是由证明者持有。
\
paradigm_state2738×1524 321 KB
图 1:按合约类型和账户划分的状态大小概述。摘自 这篇 Paradigm 文章,其中包含此图的可点击版本。
完全无状态性(Full Statelessness)是一种消除证明者存储状态需求的方案。取而代之的是,证明者存储最少的状态信息,即前一个区块的后状态根(post-state root),并随新区块一起接收一个见证(witness)。见证包含:
完全无状态性存在两种变体:在弱无状态协议(weak stateless protocol)中,区块生产者(block producer)需要向证明者提供见证,因此,它应该可以访问完整的状态。在强无状态协议(strong stateless protocol)中,用户必须向区块生产者提供见证。区块生产者聚合见证并将它们发送给证明者。用户应该可以访问与其交易和见证相关的部分状态。
部分无状态性(Partial Statelessness)是另一种允许网络参与者存储部分状态而不是全部状态的方案。其核心原则是将状态划分为两个集合。一个活跃(active)集合,由所有网络参与者存储,其功能与今天的状态相同。另一个非活跃(inactive)集合,区块生产者或证明者不必存储。如果用户想要访问非活跃集合中的状态,他们需要提供一个见证来复活(resurrect)该部分状态。非活跃集合可能包含低价值或未使用的状态。Storm 和 Georgios 的 文章 估计,以太坊至少有 7.4% 的状态不再被积极使用。但是,如果以太坊采用部分无状态性,这并不意味着只有 7.4% 的状态是非活跃集合的一部分。相反,社区需要设置必须成为活跃集合一部分的状态百分比,并据此确定状态增长的 gas 成本。因此,非活跃集合可能远大于整个状态的 7.4%。
无状态性解决方案空间的核心思想是最佳地选择谁负责向证明者提供见证,从而使以太坊能够在保持网络参与者合理硬件要求的同时最大化状态增长。 部分和完全无状态性之间的关键区别在于,在部分无状态性中,区块生产者和证明者存储相同的状态信息。相比之下,在弱无状态性中,区块生产者需要存储状态,但证明者不需要。在强无状态性中,区块生产者和证明者都不需要存储状态。然而,部分和完全无状态性并非互斥(即使术语可能暗示如此)。在图 2 中,我们提供了可能的解决方案组合的概述。
图 2:无状态性解决方案空间概述。蓝色标题对应于完全无状态性。红色标题对应于部分无状态性。紫色标题是完全和部分无状态性的组合,其中区块生产者是部分无状态的,而证明者是完全无状态的。即使在有状态协议中没有通过网络传播见证,我们也会说证明者提供必要的见证来说服自己该状态是状态树的一部分,以便强调无状态性是关于选择谁应该为某部分状态提供见证。
本文从高层次的协议设计角度探讨了无状态性和状态过期。我们旨在为从事无状态性研究的研究人员和开发人员提供以下研究问题的见解:
tldr: 区块生产者可以确定自己的状态过期规则,而不管协议设置了什么状态过期规则。
tldr: 在这两种设置中,诚实的区块生产者行为的定义是不同的;然而,理性的区块生产者存储的状态部分可能相似。
tldr: 协议设计者必须共同选择最适合以太坊的 gas 上限和状态提供架构。更多的状态增长可能会导致更糟糕的状态提供者架构。
本文不涉及弱无状态性如何实现,因此无论以太坊使用 Verkle 树、二叉树 还是 zkEVM,结果都成立。我们专注于证明者和区块生产者的角色,并将它们视为可能独立的实体,并建立在 彩虹质押 框架之上。
部分无状态性使用状态过期规则(state expiry rule)将状态划分为两个互斥且完全穷尽的子集。一个集合,活跃(active)集合,包含用户可能经常访问的状态,并由所有证明者和区块生产者存储。另一个集合被称为非活跃(inactive)集合,例如,因为此集合中的状态可能只是偶尔被访问。证明者和区块生产者不需要存储非活跃集合。
最常被研究的状态过期规则大致基于状态最后一次被访问的日期将状态划分为两个子集。例如,正如 Han 在这次演讲 中讨论的状态过期规则,可以说:如果一条状态在 6 个月内没有被访问,则将该状态从活跃集合移动到非活跃集合。在实践中,这意味着证明者和区块生产者可能会从他们的存储中删除该状态;现在希望访问该状态的用户必须提供一个见证,以将该状态从非活跃集合复活到活跃集合。作为背景,Vitalik 提出的状态过期规则 大致声明:每隔几个月将活跃集合移动到非活跃集合;用户必须提供一个见证以将状态从非活跃集合复活到活跃集合。
Ress,无状态 Reth,允许执行客户端在仅存储部分状态的情况下运行。Ress 是证明者的链下部分无状态解决方案。它没有说明区块生产者应该存储什么状态。Ress 对状态进行分区,使得见证大小很小,并且证明者必须存储的状态部分也很小。它将合约字节码分配给活跃集合,并将状态的其余部分分配给非活跃集合。这种方法不同于基于时间的方法,因为选择部分无状态性的实际动机是为了保持见证大小较小。但是,仍然希望几乎每笔交易都必须提供一个见证,这与上面提到的基于时间的方法不同。
状态过期规则旨在最大化网络活跃状态与状态流失产生的成本之间的预期价值差,同时保持最大活跃状态大小低于特定阈值。状态流失是在活跃和非活跃集合之间移动状态的过程。换句话说,状态过期规则可以解释为背包问题的目标函数,其中最大活跃状态大小是约束*.
协议确定所有证明者应遵守的状态过期规则。如果证明者有不同的状态过期规则,则一些证明者可能需要与某条状态进行交互的见证,而另一些则不需要。假设没有全局状态过期规则,但证明者使用他们自己的过期规则,那么区块生产者提供一个没有见证的区块可能会分裂证明,从而导致网络不稳定。证明者总是可以存储比状态过期规则规定的更多的状态,但绝不应该存储更少的状态。
有趣的是,区块生产者不需要遵守此状态过期规则。区块生产者可以修剪其状态树的一部分,例如,不经常访问的状态,并声明:“我拥有状态的交易包含在区块中;任何涉及我没有的状态的交易都必须提供一个见证。” 图 3 提供了一个区块生产者可以如何做到这一点的示例。考虑一个希望存储账户 1 和 2 但不存储 3 和 4 的区块生产者。为了包含仅涉及账户 1 的交易,区块生产者必须存储见证,包括账户 2 和中间节点 B。如果其他人接触不同的区块中的账户 3,我们的区块生产者需要使用 B 的新值更新其见证。
图 3:状态树示例。考虑一个想要包含与账户 1(绿色)交互的交易的区块生产者。区块生产者必须提供一个由账户 2 和中间节点 B 组成的见证(橙色)。它不必存储账户 3 和 4。
我们可能不希望区块生产者修剪其状态树的一部分,因为具有更差硬件的证明者也存储整个状态。实际上,如果协议的设计使得区块生产者总是可以合理地存储所有状态,那么他们可能不太可能修剪其状态树。然而,本文旨在强调协议设计者可以依靠区块生产者自己修剪其本地状态树视图的可能性。即使证明者是无状态的,实施状态过期规则也可能会增加状态增长,因为预计区块生产者不会存储所有状态。如果我们不受区块生产者必须持有的状态大小的限制,会发生什么?社区需要提出的问题不是鉴于当前的状态增长趋势,为什么区块生产者会修剪他们的状态,而是将状态增长到大于协议可以期望单个区块生产者存储的大小是否有益。
我们得出的结论是,区块生产者可以在本地确定状态过期规则,而不管协议设置了什么状态过期规则。 那么,状态过期规则不会最大化活跃状态对网络的价值,而是最大化活跃状态对区块生产者的价值。因此,如果证明者是无状态的,则状态过期规则不必是协议规则。设置全局状态过期规则,即使证明者是无状态的,仍然可以通过两种方式使社区受益。首先,它可以允许更多的状态增长,因为区块生产者持有的状态大小较小,因此状态增长的限制较小。其次,全局规则将有助于改善用户体验,因为所有区块生产者都表现出相似的行为。此规则可以存储在智能合约中,而不是协议规范中。首先,该规则可能应该声明它所在的智能合约不得被修剪!:wink:。
在弱无状态协议和强无状态协议中,证明者都不存储状态,而是使用见证来验证所提供状态的正确性。在弱无状态性中,预计区块生产者会存储状态并提供见证,而在强无状态性中,预计用户会这样做。
在前一节中,我们认为区块生产者可以决定存储什么状态,而不管协议对他们的期望如何。这立即将我们带到本节论点的核心:弱无状态性和强无状态性可能没有根本的区别。如果以太坊采用弱无状态协议,则区块生产者可能不会存储整个状态,并且需要见证才能与某些部分状态进行交互。如果以太坊采用强无状态协议,则区块生产者可能会存储部分状态,以便为用户提供与某些部分状态进行交互的见证。无论以太坊采用弱无状态性还是强无状态性,原则上,区块生产者都可以存储相同的状态信息。
在强无状态协议中,用户仍然需要访问状态以决定是否发送交易(例如,Uniswap 报价是多少?)并为其交易创建见证。原则上,用户可以自己存储状态,但这不切实际,因为用户必须经常更新其见证,正如 Christ 和 Bonneau 在 这篇不可能结果 中探讨的那样。相反,用户可以从状态提供者处获取此状态。状态提供者也可以称为证明服务节点(proof-serving node),如 Srinivasan 等人 (2021) 中所述。证明服务节点可以是钱包、应用程序或任何其他人。区块生产者也可以是状态提供者。弱无状态性可以被视为强无状态性的一个特例,其中区块生产者被期望成为用户的证明服务节点。
理解弱无状态性和强无状态性之间的区别很重要,即使它们非常相似,因为它可以帮助定义诚实的区块生产者行为可能是什么样的。定义诚实的区块生产者行为至关重要,因为协议可以使用许多工具来迫使不诚实的区块生产者表现得更像诚实的区块生产者。这些工具的示例包括 MEV-Burn 和 FOCIL。如果社区决定区块生产者必须是证明服务节点,那么 FOCIL 可以强制包含没有提供见证的交易。如果社区选择其他方式,那么 FOCIL 只能在交易附带见证的情况下强制包含交易。重要的是,对于每个未来的协议,必须首先定义诚实的区块生产者行为是什么,然后定义这些工具的功能是什么。
目前,状态增长受到证明者可以合理预期持有的状态大小的限制。如果证明者是无状态的,则此约束消失。也许状态大小仍然受到可以预期区块生产者持有的状态的限制?但是,如果区块生产者不履行证明服务节点的角色,也许这也不是一个约束。在无状态的以太坊协议中,状态增长对 gas 上限仍然有哪些限制?
也许我们想确保存档节点(archive node),即使以太坊是无状态的,这些节点大概也会存储整个状态,能够跟上链的顶端。也许,我们想确保证明服务节点架构中有足够的冗余和可访问性,以向用户保证他们的状态始终可以轻松地免费访问。但请注意,这些约束与当前状态增长面临的约束非常不同。今天,状态增长受到证明者能力的约束,这对于协议的运行至关重要。将来,约束是由以太坊想要提供的用户体验保证形成的,这是一个不同的权衡。
作为协议设计者,我们必须共同决定每个时间单位的最大状态增长和最能满足以太坊需求的服务节点架构。如果允许大量状态增长是目标,则证明服务节点架构必须是健壮的。如果通过区块生产者和 Portal 等网络确保强大且可自由访问的状态存储更为关键,则可能需要缓和状态增长。
为了做出这个决定,协议设计社区需要更好地理解对证明服务节点架构的要求。我认为探索一种证明服务节点架构可能很有趣,在这种架构中,没有单个实体持有整个状态,但应用程序负责与其应用程序相关的状态,也许钱包负责与其用户相关的状态。该系统模仿了状态租金(state rent) 的基本思想:增加状态的应用程序和用户不应能够一次性支付永久成本。在这个系统中,存储状态的成本将由增加状态的应用程序或用户承担。
- 原文链接: ethresear.ch/t/a-protoco...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!