[TOC]

AIP-65 - 可退还的状态字节存储费

一、概述

目前提出了一个储存费收费方案的进化版,在此方案中,除了反映单个状态项目通过验证数据结构带来的存储影响的“插槽押金 (slot deposit)”之外,还将根据状态项目本身在当前状态所占用的字节数量来征收和返还一种新的储存费用(暂称为“字节押金 (bytes deposit)”)。

具体而言,那种对更新庞大状态数据时施加重大惩罚的旧有“免费配额”机制已被取消。

更新后的方案更能与交易对磁盘空间消耗的现实情况相符合,因此为开发者提供了一个更好的经济基准,以便优化交易的成本。

二、背景 - 为什么存在“免费字节配额”

一般来说,Aptos 节点在磁盘上保留两类区块链数据:

  1. 最新状态:最新状态中的项目及其关联的认证数据结构 — 网络必须将它们保留到某个交易删除相关状态为止。此类存储应该定价高,并在删除时予以退款。
  2. 账本历史:交易本身及其输出,包括“写入集”,即更新状态项目的集合 — 所有更新的项目的完整信息。

假设,一个大型状态项的大小略有增加:

  1. 最新状态的总大小会略微增加。
  2. 更新的项目的全部内容将最终出现在写入集中,这是账本历史的一部分,并且会一直保留在磁盘上,直到交易版本足够旧以便被修剪。

历史上,存储费收取方案旨在防止这两类存储消耗变得过于廉价而填满磁盘。具体而言,为了确保磁盘不会被最新状态项填满,字节的存储费很高;为了确保磁盘不会被更新大型项目生成的写入集填满,对更新的状态项的整体费用较高;最后,为了确保常见用例的成本合理,每个项目有 1KB 的“免费字节配额” — 不仅较小的项目更便宜,它们还可以免费修改。

然而,大于免费配额的项目重复修改非常昂贵。

三、提议

旧方案对频繁修改的大型状态项施加了严厉的惩罚,因此为小于免费配额的项目带来了强烈的激励,这迫使开发者在设计合约的存储粒度时做出尴尬的权衡,并可能通过激励更多状态项而使状态爆炸问题变得更糟。

通过引入AIP-57,它为每块交易输出大小添加了限制,因此写入账本历史的磁盘带宽实际上被上限限制。结果,存储特定长度账本历史(以天为单位)所需的总磁盘空间被上限限制。为了简化模型,我们建议将这部分成本视为恒定的,并不适用于存储费用的收费。因此,根据状态项的大小收取的费用仅反映了永久存储影响,并且应该随着项目大小的增长而递增收费,并在它占用的槽位被清理时退还。

1. 目标

移除每个槽的免费配额,对合理的大型项目更加友好。

2. 不在范围内

请注意,此AIP涉及磁盘空间消耗的存储费。与此相关的另一个关注点是与延迟相关的问题,这由 Io Gas 处理。在那方面需要进行的更改也由AIP-59涵盖。

四、 影响

频繁更新的较大状态项现在更加便宜。并且在删除时,按字节支付的费用是可退还的。因此,开发人员现在可以根据事物的访问(修改)模式直接决定存储的粒度,而不必担心修改较大的项目会受到惩罚。

定价降至每个槽 4000 个八位字节,每个字节 40 个八位字节,并且删除了1KB的免费配额。因此:

  1. 分配小于250字节的项目比以前更便宜。
  2. 分配大小在250到4K字节之间的项目将略微更昂贵,但更公平。价格增加在1KB处约为60%。
  3. 仅触及槽> 1KB不再会产生惩罚,因此此类交易变得更便宜。如下表中的 MutateLargeTokenV2、UpgradeLarge 等所示。

常见交易类型的燃气成本之前与之后的对比(假设 gas_unit_price=100 octas):

频繁更新的大型状态项现在更便宜了。并且在删除时,为字节支付的费用是可退还的。因此,开发者现在可以根据事物的访问(修改)模式直接决定存储粒度,而不必担心修改大型项受到惩罚。

定价降低到每个槽位 4000 octa,每个字节 40 octa,并且移除了 1 KB 的免费配额。结果是:

  1. 分配小于 250 字节的项目比以前更便宜。
  2. 分配大小在 250 到 4 K 字节之间的项目将比以前稍微贵一些,但更公平。价格增加在 1 KB 时达到峰值,大约增加了 60%。
  3. 仅仅触及大于 1 KB 的槽位不再受到惩罚,因此这类交易显著变得更便宜。如表中所示的 MutateLargeTokenV2、UpgradeLarge 等。

常见交易类型的 Gas 成本(假设 Gas 单位价格为 100 octa):在之前和之后的对比:

交易类型原始 5k/槽 50/字节 w/ 1KB 免费配额4k/槽 40/字节变化
转账66100.0%
第二次转账66100.0%
创建账户100499298.8%
创建转账100699498.8%
MintTokenV2511633123.9%
MutateTokenV277100.0%
MintLargeTokenV21620145389.7%
MutateLargeTokenV2175590.5%
创建抵押池20182347116.3%
RotateConsensusKey4564142.2%
JoinValidator1004559511.1%
AddStake4561130.3%
UnlockStake938422.2%
WithdrawStake99100.0%
LeaveValidatorSet1004558100.2%
创建集合100696295.6%
创建令牌首次1509148998.7%
MintTokenV188100.0%
MutateTokenV150948394.9%
MutateTokenV12ndTime88100.0%
MutateTokenAdd10NewProperties1264533.3%
MutateTokenMutate10ExistingProperties1212100.0%
PublishSmall10651122105.4%
UpgradeSmall717098.6%
PublishLarge131661105584.0%
UpgradeLarge10812144313.3%

六、替代解决方案

Tip

原作者注:N/A

七、规范

  1. 移除了每个槽位的“免费字节”配额。相反,一个状态项的所有字节都被统一定价,以反映在状态数据库中永久占用空间的成本。
  2. 将字节的存储费用视为押金,这是可退还的。
  3. 当一个槽位在修改而增加大小时,会被额外收取押金。
    1. 传统槽位如果没有支付字节押金,不会为免费分配的字节收费。
    2. 考虑到定价变化,只收取到总押金不超过 当前每字节价格(current_price_per_byte) * 当前字节数(num_current_bytes) 的点。
  4. 当槽位在修改而减小大小时,不退款,以简化实现和推理。
  5. 如果槽位在修改时大小没有变化,即使定价变化也不收费。
  6. 只在删除时退款。

八、参考实现

https://github.com/aptos-labs/aptos-core/pull/11333

https://github.com/aptos-labs/aptos-core/pull/11279

九、测试(可选)

Tip

译者注:原文未填写

十、风险和缺点

由于定价变化,某些交易的成本增加了。具体来说,那些分配(不是修改)的槽位,其大小在 250 字节到 4K 字节之间。但这是更公平的。 由于价格的调整,有些交易的成本提高了。特别是对于那些创建(不是修改)新槽的交易,且这些槽的大小在 250 字节到 4K 字节之间。不过,这样的改变使得价格更加公正。

十一、时间表

1. 建议的实施时间表

1.10 版本,2024 年初

2. 建议的开发者平台支持时间表

3. 建议的部署时间表

1.10 版本,2024 年初

十二、安全考虑

永久存储的价格降低了20%,我们认为这样的权衡是值得的。