Alert Source Discuss
🚧 Stagnant Standards Track: Core

EIP-7609: 降低 TLOAD/TSTORE 的基本成本

通过降低基本成本并引入超线性定价模型来提高 TLOAD/TSTORE 的效率。

Authors Charles Cooper (@charles-cooper), James Prestwich (@prestwich), brockelmore (@brockelmore)
Created 2024-02-01
Discussion Link https://ethereum-magicians.org/t/eip-7609-reduce-transient-storage-pricing/18435
Requires EIP-1153

摘要

降低 TLOAD/TSTORE 的基本成本,同时引入超线性定价模型。这提高了 TLOAD/TSTORE 在常见用例中的效率,同时提供了一种定价模型来防止 DoS 攻击。

动机

EIP-1153 引入了一个新的存储区域,称为“瞬态存储”。它的行为类似于存储(按字寻址并在调用帧之间保持不变),但与存储不同的是,它在每次交易结束时都会被擦除。 在 EIP-1153 的开发过程中,定价被设置为与预热存储的加载和存储相同。 这有两个原因:EIP 的概念简单性,并且它还解决了对两个相关 DoS 向量的担忧:能够分配过多的瞬态存储,以及在恢复的情况下回滚状态的成本。

EIP-1153 启用的最重要的用例之一是廉价的重入保护。 事实上,如果对于前几个槽而言,瞬态存储足够便宜,则可以在语言级别默认启用重入保护,而不会给用户带来太多负担,同时防止最大——也是最昂贵的——智能合约漏洞。

此外,瞬态存储似乎从根本上定价过高。 它的定价不与退款互动,它只需要在合约加载时进行新的分配(与内存相反,内存需要在每次调用时进行新的分配),并且不与物理数据库互动。

本 EIP 提出了一种定价模型,该模型按每个分配收取额外的 gas 费用,这对于常见情况(每个合约写入的槽少于约 95 个)来说更便宜,同时使使用瞬态存储进行 DoS 攻击的成本高得令人望而却步。

规范

本文档中的关键词“必须”,“不得”,“必需”,“应”,“不应”,“推荐”,“不推荐”,“可以”和“可选”应按照 RFC 2119 和 RFC 8174 中的描述进行解释。

建议 TLOAD 的 gas 成本为 5 gas。 建议 TSTORE 的 gas 成本为 8 gas + expansion_cost,其中 expansion_cost 计算为 1 gas * len(transient storage mapping)(如果该键尚未在瞬态存储映射中),否则为 0 gas。

用伪代码表示:

G_LOW = 5
G_MID = 8

SLOPE = 1

def gas_tload(_key):
    return G_LOW

def gas_tstore(key, transient_mapping):
    cost = G_MID
    if key not in transient_mapping:
        cost += SLOPE * transient_mapping.size()
    return cost

理由

Gas

在基准测试中,发现 TLOAD 消耗的 CPU 时间与 MUL 相似,而 TSTORE 消耗的 CPU 时间约为 MUL 的 1.5 倍。 因此,分别为 TLOADTSTORE 选择了值 G_lowG_mid

向后兼容性

未发现向后兼容性问题。

安全考虑

在给定 30m gas 的情况下,可以在单个合约上分配的最大瞬态槽数为大约 7,739(x(x-1)/2*1 + 8*x = 30_000_000 的解),总计 248KB。

如果你使用调用新合约的策略(每个合约都旨在最大化瞬态存储分配),一旦 TSTORE 的成本超过调用冷合约的成本(2600 gas),则可以在交易中分配的最大瞬态槽数可以按如下方式求解:

solve for SLOPE * <num slots> == 2600, => num_slots == 2600
gas_used_by_contract = 2600 + SLOPE * num_slots * (num_slots - 1) / 2 + G_MID * num_slots == 3402100
block_gas_limit = 30_000_000
num_calls_per_txn = block_gas_limit // gas_used_by_contract ~= 8.8
max_transient_slots = num_calls_per_txn * num_slots == 22927

因此,使用此方法在单个交易中可以分配的最大瞬态槽数约为 23,000 个,总计 736KB。 与当前的 gas 计划(允许分配大约 30_000_000 / 100 * 32 == 9.6MB 值的内存)相比,这是客户端可以使用瞬态存储分配的总内存的净 减少,因此本 EIP 对瞬态存储可以使用的资源施加了更强的限制。 作为比较,在给定的交易中,客户端可以通过 SSTORE 分配的总内存量为 30_000_000 / 20_000 * 32,即 48KB。

请注意,此上限随 gas 限制线性缩放,这在考虑未来区块 gas 限制增加时是一个有用的属性。

版权

通过 CC0 放弃版权及相关权利。

Citation

Please cite this document as:

Charles Cooper (@charles-cooper), James Prestwich (@prestwich), brockelmore (@brockelmore), "EIP-7609: 降低 TLOAD/TSTORE 的基本成本 [DRAFT]," Ethereum Improvement Proposals, no. 7609, February 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7609.