规范
为方便阅读的 AI 翻译,可能不准确或已过时。在治理、投票和争议中,英文原文是唯一权威文本。准确表述请参阅 GitHub 原文。
GitHub 英文原文 ↗## 摘要 重新定义内存扩展成本为线性,并强制每个交易的最大内存使用量。 ## 动机 目前,EVM 内存使用受到二次扩展成本和 63/64 规则的限制。一个交易的理论内存限制至少为 26 MB。历史交易分析显示,平均内存使用量约为 2 KB,最大观察到的内存使用量约为 2 MB。 基准测试还表明,当前的内存扩展公式对实际资源使用收费过高。 此更新将成本与实际资源消耗对齐。它使内存使用更加可预测,特别是对于依赖于大内存分配的合约。 ## 规范 内存扩展成本重新定义为: ```python memory_size_words = (memory_byte_size + 31) // 32 memory_cost = memory_size_words // 2 ``` 最大内存使用量限制为 8 MB。内存分配在调用上下文中受到以下规则的限制: 1. 设 `k` 为当前调用使用的内存,`j` 为父调用使用的内存。 2. 子调用可用的剩余内存为: ```python remaining_memory = 8 * 1024 * 1024 - j - k ``` 3. 一旦调用返回,内存将返回到池中。 4. 如果调用超过剩余内存限制,则会异常停止,消耗该调用帧中剩余的所有 gas。 ## 向后兼容性 该提案与现有合约高度兼容。几乎所有标准 EVM 操作仍然有效,ERC-4337 合约继续正常运行,因为子调用内存在完成后会释放。将使用历史以太坊交易的重放测试来量化兼容性。 然而,分配超过 8 MB 内存的合约现在将异常停止。 ## 安全考虑 将内存扩展到 8MB 上限的成本为 131,072 gas。结果是扩展内存的成本低于当前成本。可能需要调整 RPC 节点的并发限制,以防止 OOM 问题。 ## 致谢 本 MIP 中的提案基于两个先前的 EIP 文档。此外,与 Charles Cooper 的对话对开发 Monad 内存模型具有指导意义: - [EIP-7686](https://eips.ethereum.org/EIPS/eip-7686) (@vbuterin) - [EIP-7923](https://eips.ethereum.org/EIPS/eip-7923) (@charles-cooper, @qizhou) MIP-3 与 EIP-7686 的不同之处在于,EIP-7686 定义了内存限制与 gas 限制之间的直接关系,而与 EIP-7923 的不同之处在于 MIP-3 不采用基于页面的抖动成本模型。 ## 版权 通过 [CC0](../LICENSE.md) 放弃版权及相关权利。
论坛讨论
-
MIP3 - Linear EVM memory cost This proposal reprices EVM memory expansion from a quadratic cost model to a linear one. To bound total memory usage within a block, each transaction is explicitly limited by its peak memory usage. The motivation is to better align EVM gas costs with real resource usage and to introduce an explicit invariant on total memory usage at the block level. Any feedback or discussion is appreciated on: - the proposed linear memory cost model - the explicit per-transaction memory limit - potential DoS concerns - developer ergonomics and usage concerns
-
Hello, I have questions to the design and spec: 1. How does the call which exceeds memory exit? revert or exceptionally halt? If revert, does the gas to extend memory get charged before reverting? and other instruction gas charges (esp. *CALL )? exceptionally halt is more consistent with current OOM behavior (out-of-gas), but revert is more friendly. The spec says “revert” but I want to confirm that’s what was meant and spec out the fine details. 2. For all calculation related to memory limit, the memory size isn’t rounded up to the nearest word, i.e. if caller frame allocates `limit - 1byte` memory, callee frame can still allocate `1byte` of memory? This is in the spec, but want to confirm.
-
- Can we expand discussion with EIP-7686 and EIP-7923 in the Rationale section, i.e. why is MIP-3 chosen over them? (my understanding is that EIP-7686 would combine unfavorably with Monad’s “charge-gas-limit” rule, what about the paging from EIP-7923?) - Similar to EIP-7923, behavior of MSIZE after the activation should be confirmed (esp. given the lack of rounding to word in memory limit calculation.) In other words - would MSIZE return limit or limit - 1byte in the case mentioned in (2.)?
-
Some Responses: - Exceeding the memory limit causes the current call frame to revert rather than halt. One rationale for this decision is compatibility with ERC-4337 bundlers for the following reason: if exceeding the memory limit resulted in an exceptional halt a transaction could DOS erc4337 bundlers by using the memory limit. If compatibility with erc4337 is not necessary then this can be changed to halt.
-
- Expansion cost remains in terms of 32 byte word expansion. This will be defined more explicitly in the MIP. - EIP-7686 and EIP-7923 are designed for ethereum execution specifically. For example in EIP-7686, it defines a strict bound on memory expansion via gas. This defines the amount of expandable memory to be linearly dependent on the amount of gas forwarded in the call. This is not compatible to the constraints of Monad execution. As it would cause a higher memory footprint per transaction. - MSIZE semantics are unchanged. It returns the size of active memory in bytes. So the case where caller frame allocates limit - 1byte memory is rounded up to the limit memory. The child call would not have any remaining memory to allocate.