本提案为 Qtum 联合创始人以及核心开发工程师 Jordan Earls 发布在 Github 的有关 Qtum x86 虚拟机的最新进展,当中他提出了一种关于存储的全新技术提案 —— Qtum-x86 虚拟机中所有存储区都可实现租赁机制,高效的节省了虚拟机内存。就目前而言,在 EVM 基础设施不受影响下,全新租赁机制是一种「被动」的方式去实现,不需要特殊的合约逻辑来处理相关的租赁过程,也不需要支付所消耗存储区的租金。该技术设计将有效地限制节点需要存储的数据总量,同时还能限制轻量级 SPV 节点对智能合约进行有效治理与交互所需的总空间。

量子链创始人帅初告诉链闻:链上资源租赁实现方式不同于现有的已提出的大多数方案。这其中一个最大的担忧是,智能合约本身已经相当复杂了,租赁方案所带来的额外的复杂性会大大增加智能合约代码中的问题和漏洞利用的可能性。该提案以一种不同的方式利用 DeltaDB 的特性从而使租赁系统对生态系统有益,而在大多数情况下不需要任何额外的智能合约逻辑。

原文标题:《Qtum-x86 虚拟机实现存储区租赁,高效节省虚拟机内存》
文章来源:公众号「Qtum 量子链」

1 为什么会提出 EVM 租赁机制?

区块链基础设施技术背后的逻辑都面临着一个问题:「区块链虚拟机数据越来越多怎么办?」,因此存储空间的消耗长期以来一直是区块链领域内一个受人关注的话题。任何区块链,尤其是具有智能合约功能和附加状态的区块链,据估计存储空间的需求会在短短 10 年内超出大多数计算机和服务器的存储能力

这种磁盘空间需求的膨胀将导致全节点会集中到那些能负担得起价格高昂的具有非常大存储的价格的人手中。简而言之,未来就会出现由于存储设备的门槛导致资源的集中,也就与去中心化背道而驰。

举例而言,数年来随着区块链市场的蓬勃发展,以太坊交易数量越来越多,单个区块体积的最大值限制使得区块空余空间显得越来越小。如图,相比比特币而言以太坊的区块大小更加呈现增量上升的模式,甚至在 2017 年后以太坊的区块大小由不足 0.1TB 上升至接近 0.4TB。

如何解决全节点的数据膨胀与状态爆炸?Qtum 给你独特设计思路比特币与以太坊区块体积大小

因此,越来越多的开发者和相关技术都在进行底层基础设施的探索,想要商业应用于区块链技术真正实现技术的融合,就需要不断去提出新的思想和新的技术探索,因此本文提出共享存储的设想,帮助区块链的基础设施早一步更好的搭建商业设施的桥梁。

2 QIP-17:Qtum-x86 内的存储区租赁

对此在 Qtum x86 设计上所做的变更可以划分为以下 3 个部分:

  • DeltaDB 重新传播和租赁行为
  • 「休眠」状态的智能合约行为
  • 「唤醒」休眠状态的方法

首先,用于不同状态的术语解释

  • 活跃:该状态要求支付一定的租金,从而在区块链上保持其活跃性并易于访问
  • 休眠:未能在适当的时间内支付租金时所处的状态,并且在没有通过交易进行重新传播的情况下不能通过智能合约直接访问
  • 唤醒:这是将休眠状态恢复到活跃状态的动作,以便可以再次通过智能合约直接访问它
2.1 DeltaDB 重新传播和租赁行为

合约的每一个状态,包括它自己的字节码,都有一个通过区块高度表示的租金计时器。一旦该计时器值为 0,就会从活跃状态切换到休眠状态,并且节点可以安全地从其内部数据库中删除与该状态相关的大部分数据。当访问或修改状态时,会隐性地进行租金支付,这会被计入至该操作的 gas 开销中。当通过访问数据进行租金支付时,该状态会将其计时器重置为 RENT_TERM。无法通过预付款的方式将一个状态的计时器设置为大于 RENT_TERM 的值。

使用 DeltaDB 当前的共识模型时,读取一个状态(通常)不会向 DeltaDB 证明树添加新的 delta (状态更改 / 通知)。使用本文提出的存储区租金提案,每个状态访问都会通过向 DeltaDB 证明树提交一个 delta 从而引起状态的「重新传播」。虽然这对合约甚至大多数区块链开发人员而言都没有影响,但还是会带来许多副作用:

  • SPV (轻钱包)节点可以证明状态最近一次租金支付的时间
  • 相反,它允许可以从 SPV 或全节点的内部数据库中删除状态和大多数证明开销的证明
  • SPV 节点可以更快地获得状态数据的抗审查证明,通过更频繁地传播合约中最常用的数据,需要扫描的区块也更少
  • 除了唤醒状态所需的开销之外,这不会消耗额外的区块空间,因为 DeltaDB 证明树会以单个 32 字节长的哈希值的形式保存在区块头中,而不会带来其他的开销
  • 由于能够证明不再需要比 RENT_TERM 更旧的数据, 这可以大大降低 Qtum-x86 区块链理论上的最大磁盘空间消耗,尤其是在进行修剪操作时。通过修剪,经过 500 个区块后,大多数唤醒状态下的交易就不再需要存储了

当然,这将限制节点存储的数据仅限于持续共识所需的数据。区块链上的证明总是可用的,例如出版证明等用例。然而,这些证明通常只会被添加一次,并且之后也是偶尔才会被访问,因此对于共识而言是非必要的。

对于每个休眠状态,节点需要记录以下数据:

  • 状态最后一次传播所处的区块高度(即最后一次支付租金的时间)
  • 索引数据的密钥哈希
2.2 智能合约

大多数关于存储租赁设计的提案都要求智能合约具有明确且易错的租金管理和意识。在这种设计中,一切都是隐性的,在特定合约设计之外不需要进行租金检测操作。通过这个提案,一定程度上会对不可避免的异常行为产生影响,包括合约试图访问休眠状态时抛出的异常。

  • 与以太坊的异常模型会消耗所有的 gas 不同,该机制只会消耗合约产生异常时的那部分 gas,以及一定的「异常税」
  • 所有修改后的状态都会被恢复,这点与以太坊的异常模型类似,并且这些被恢复的状态不会在 DeltaDB 中传播
  • 在发生异常之前访问的所有活跃状态都会有租金支付,因此这些状态会在 DeltaDB 中传播
  • 如果活跃状态被修改了并且实际执行过程中从未读取过该状态,则状态不会有租金支付,因此也不会在 DeltaDB 中传播。如果执行没有以异常结束,则将传播修改后的新状态
  • 如果执行附加了唤醒状态,则此状态会被标记为「已访问」,因此即使在执行中出现异常,该状态仍会在 DeltaDB 中传播并恢复。请注意,恢复状态下存在「唤醒税」,必须在合约执行开始前支付。如果发送到账户的用于支付唤醒税的 gas 数太少,则将不会进行任何恢复操作,除了返回表明执行失败的收据之外,不会执行其他的操作并且所有 gas 都会被消耗掉
  • 如果执行附加了唤醒状态,但该状态已经处于被唤醒的状态,那么这个已经处于唤醒状态的状态将被忽略,并且也不会消耗任何 gas。这使得那些为确保合约成功执行而谨慎地加入即将到期的唤醒状态的人不必支付成本。附加的休眠状态将被唤醒并需支付唤醒税
  • 在上述这些被附加的状态已经处于唤醒状态的情况下,该状态会被认为是已访问的,因此会在 DeltaDB 中传播并且 INDEX_TAX + PROP_TAX 将按状态键收费

这种隐性租金支付和异常设计方案意味着大多数合约完全不需要担心租赁机制的正常运作。但是,对于那些需要对租赁机制有一些自我意识的合约,则需要添加一些额外的系统接口:

如何解决全节点的数据膨胀与状态爆炸?Qtum 给你独特设计思路

2.3 GAS 模型

当前 Qtum-x86 虚拟机中用于存储的 gas 模型设计还没有完全实现,不然要是实现了的话,本提议将完全地改变它。所以,现在最好是暂时放下手中的设计工作。

定义

如何解决全节点的数据膨胀与状态爆炸?Qtum 给你独特设计思路

2.4 实际操作

如何解决全节点的数据膨胀与状态爆炸?Qtum 给你独特设计思路

虽然这个操作列表看起来非常大,但实际上它是非常公式化的,并且在代码的实现过程中不会太难。它是非常有规则的,应该只需要处理很少的边界情况。上面定义的每个常量或方法应该是不言自明的,并且应该考虑到节点和更大网络所需的所有成本。

这种方法的一些风险在于退款必须是保守的,以避免出现下面这种投机取巧的情况:例如,先将数据写入状态,然后将状态修改为较小的大小,而不是在开始简单地就写入较小的状态。退款行为与以太坊不同,执行操作后的任何剩余的 gas 都会被发送回收款人,其中数量不超过发送给合约的总 gas 数。如果允许发送回多于合约中发送的 gas 数,那么可以人为地利用高的 gas 价格输出 Qtum,从而以比初始支付时更高的 gas 价格进行退款。

2.5 AAL 账户抽象层修改

为了适当地修剪合约交易中的无关数据,所有的合约执行和交易创建都将经由 AAL 支出并进行压缩。这也会极大地简化将来其他的 QIPs,例如基于 UTXO 模型的「一次性拥有」状态的提案。目前,合约执行仅在执行中的资金实际用于智能合约时才由 AAL 支出。此外,合约创建交易仅在合约自毁时花费。这允许 SPV 节点利用一些额外的功能来跟踪合约行为,但这会以在 UTXO 集中保留重复且不太相关的数据为代价。DeltaDB 中的 SPV 目标访问和跟踪方法将有效地取代此功能。

2.6 新的节点分类

目前,Qtum 生态系统中有三种主要类型的节点:

  • 存档节点 :该类节点包含整个区块链的数据。UTXO 集被修剪至不包含重复数据,但所有已花费的交易数据会保存在磁盘上,数据存取较慢。该类节点可用于任何用例,包括委托,常规钱包,历史数据分析,开发等。
  • 修剪的全节点: 该类节点类似于一个全节点,会下载并验证整个区块链,但会删除那些可证明不被使用的数据。特别地,这包括已花费的交易数据以及旧的区块数据。除历史数据分析外,该节点能够处理全节点的所有用例。
  • SPV 节点 :这种类型的节点通过按需下载与当前钱包「相关」的数据以及整个区块链的区块头来进行验证和证明。该类节点是非常轻量级的,通常用于移动设备和「快速同步」的钱包。节点是去中心化的,但会受审查的影响,因为无法证明它所连接的全节点是否具有应该存在的数据。通常认为这种最终的安全性是稳定的,但容易受到女巫攻击。这种类型的节点通常仅可用于钱包和一些有限类型的智能合约的开发。值得注意的是,它不能用于委托。

基于本提案提出的新功能和可证明的行为,提出了一种新的节点分类方案:快速开发节点。该类节点使用了 SPV 节点的通用安全范例,并且初始时需要下载以下数据:

  • 使用最佳区块状态树根节点的完整 EVM 数据(这是无法避免的)
  • 区块链的所有区块头(与 SPV 相同)
  • DeltaDB 证明以及那些最近 RENT_PERIOD 区块的数据(根据区块头的 DeltaDBRoot 进行验证)。修改后的数据可以在处理时进行修剪
  • 相关的 UTXOs 和当前受控钱包的证明(与 SPV 相同)

按需下载的数据包括:

  • 为新区块委托 UTXO
  • 用于证明 UTXO 存在性的 UTXO 证明(即区块哈希和 merkle 路径),然后接受区块将其作为委托花费
  • 需要已花费的用于委托 UTXO 的 UTXOs 的证明(与 SPV 节点相同)
  • 需要已花费且为相关地址创建的 UTXOs 的证明(与 SPV 节点相同)
  • 需要与合约交互并跟踪 RENT_PERIOD 内的 DeltaDB 状态变化的交易(不仅仅是 UTXO)。交易数据在执行后被修剪,只留下 DeltaDB 跟踪数据
  • 正在进行的区块头下载

对于委托和安全性这类关键目的而言,这种方案并不是安全的,因为它的核心安全性仍然是由 SPV 保证的。然而,对于智能合约开发而言这已经完全足够了,同时也可作为 SPV 节点的一个功能更强大的版本。历史合约执行可以忽略,但进行中的新合约执行可以完全地被执行和跟踪。最初的同步过程只会比 SPV 慢一点,主要是因为需要下载完整的 EVM 和修剪的 DeltaDB 数据。带宽成本也只比 SPV 节点略高,主要用于完整地下载智能合约执行所涉及到的所有交易。

2.7 原理

这种特定的租赁实现方式不同于现有的已提出的大多数方案。这其中一个最大的担忧是,智能合约本身已经相当复杂了,租赁方案所带来的额外的复杂性会大大增加智能合约代码中的问题和漏洞利用的可能性。该提案以一种不同的方式利用 DeltaDB 的特性从而使租赁系统对生态系统有益,而在大多数情况下不需要任何额外的智能合约逻辑。

此外,该提案的一个重点是将节点达成共识的所需和其他内容分离开来。将那些很少访问且永远不会更新的数据上链是完全可以接受的,但这些数据对节点而言应该是无关的。当然,仍然可以证明数据在某个区块高度时在区块链上的存在性,但是,预计它不会被网络上的大多数节点直接存储和访问。这种证明可以在不消耗任何会带来 gas 开销的区块链资源的情况下完成。此类历史数据可以转移到归档节点上。对于仅需要访问某个智能合约的休眠数据的应用程序,可以使用部分归档节点。这基本上是一个标准的修剪节点,但它会存储相关智能合约的完整历史数据。

2.8 策略

这将在 Qtum-x86 的初始版本中实现。在发布后更改该存储模型是非常困难的,因此,在已经实现的情况下推出 Qtum-x86 是有很大好处的。

待实现

  • 需要计算不同的 RENT_TERM 值的理论上的数据上限
  • 需要计算对于一个合约执行的完整区块而言,DeltaDB merkle 树的大小,以及一个典型的区块
  • 这并不能完全消除对存储所有数据的「归档节点」的需求。为了无信任地同步一个全节点,仍然必须且 / 或需要从区块数据重建所有的「休眠」数据,以便证明区块链的当前状态是有效的

来源链接:mp.weixin.qq.com