From c9c8da97b18a9c4ae4e0092f5747a8e9f4acb15e Mon Sep 17 00:00:00 2001 From: vbuterin Date: Mon, 15 Apr 2024 14:32:04 +0200 Subject: [PATCH 1/4] Create eip-7669.md --- EIPS/eip-7669.md | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 EIPS/eip-7669.md diff --git a/EIPS/eip-7669.md b/EIPS/eip-7669.md new file mode 100644 index 00000000000000..f7c9d22e7ec8be --- /dev/null +++ b/EIPS/eip-7669.md @@ -0,0 +1,75 @@ +--- +eip: 7669 +title: Linear EVM memory limits +description: Adjust memory limits and gas limits of sub-calls to create a clear linear bound on how much total memory an EVM execution can consume +author: Vitalik Buterin (@vbuterin) +discussions-to: https://ethereum-magicians.org/t/eip-linear-evm-memory-limits/19448 +status: Draft +type: Standards Track +category: Core +created: 2024-04-15 +--- + +## Abstract + +Add a hard memory limit equal to the gas limit of the current context. Make the maximum gas cost of a sub-call depend on the memory used in the current context. The two rules together ensure that a transaction with N gas can use at most N bytes of memory. + +## Motivation + +Today, memory pricing rules are complicated: we have the quadratic cost for expanding memory as well as the 63/64 rule for how much gas can go into a child call. This also makes it extremely hard to calculate a maximum possible amount of memory required to process a given EVM execution. + +The rules in this post simplify these rules, and add a new hard limit: an EVM execution with N gas can require at most N total bytes of memory to process. This limit is tight: there are easy ways for an N-gas call to use `N - O(1)` bytes of memory. + +## Specification + +Change `memory_cost` from: + +```python +memory_size_word = (memory_byte_size + 31) / 32 +memory_cost = (memory_size_word ** 2) / 512 + (3 * memory_size_word) +``` + +To: + +``` +memory_size_word = (memory_byte_size + 31) / 32 +memory_cost = 3 * memory_size_word +``` + +Additionally, if a memory expansion would lead to `memory_byte_size` strictly exceeding the current call's initial gas limit, revert with an error. + +When making any type of call, change the maximum gas limit from the current [EIP-150](eip-150.md) definition: + +```python +def max_call_gas(gas): + return gas - (gas // 64) +``` + +To: + +```python +def max_call_gas(gas, memory_byte_size): + return gas - max(gas // 64, memory_byte_size) +``` + +## Rationale + +With this EIP, there is a simple EVM implementation that can process an N-gas call using an N-byte bytearray as memory: allocate all bytes to the current context, when doing a child call use the remaining memory starting from the position `memory_byte_size` for the child call's memory, and so on recursively. + +Having this clean invariant is useful for EVM implementations, especially EVM implementations in constrained environments (eg. ZK-SNARK provers). + +The 3 gas per word memory expansion cost is retained because it is equivalent to MCOPY, and so the operation of clearing memory at the end of a child call (cheap in regular machines, but more expensive in ZK-SNARKs and other unusual contexts) can be implemented with the same logic as that used to implement the MCOPY opcode itself. + +The 63/64 rule is maintained in order to maintain the current de-facto call stack depth limit of roughly `1 + log((gaslimit + 6300) / 6400) / log(64/63) = 537`. + +## Backwards Compatibility + +It is theoretically possible for EVM code that works today to fail to work under this new EIP, if that code accesses a high index in memory but is called with a low gas limit. However, almost all EVM execution consumes far more code than it uses bytes of memory. For example, for a call to cause even a single state change, it must have at least 5000 gas. This would allow it 5000 bytes of memory, which is greater than that used by almost all applications. More complex applications would have even higher limits. + +## Security Considerations + +No security concerns were raised. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From e56d8b07ed3050329903bbd9bb803e1517e8419b Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:39:10 -0400 Subject: [PATCH 2/4] Update and rename eip-7669.md to eip-7686.md --- EIPS/{eip-7669.md => eip-7686.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename EIPS/{eip-7669.md => eip-7686.md} (99%) diff --git a/EIPS/eip-7669.md b/EIPS/eip-7686.md similarity index 99% rename from EIPS/eip-7669.md rename to EIPS/eip-7686.md index f7c9d22e7ec8be..47351f7d116cc3 100644 --- a/EIPS/eip-7669.md +++ b/EIPS/eip-7686.md @@ -1,5 +1,5 @@ --- -eip: 7669 +eip: 7686 title: Linear EVM memory limits description: Adjust memory limits and gas limits of sub-calls to create a clear linear bound on how much total memory an EVM execution can consume author: Vitalik Buterin (@vbuterin) From 4f59ff19be21b6b6a67ede369672093a5ffcf6dc Mon Sep 17 00:00:00 2001 From: vbuterin Date: Thu, 18 Apr 2024 11:53:29 +0200 Subject: [PATCH 3/4] Update EIPS/eip-7686.md Co-authored-by: Andrew B Coathup <28278242+abcoathup@users.noreply.github.com> --- EIPS/eip-7686.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7686.md b/EIPS/eip-7686.md index 47351f7d116cc3..9e4dd5f6e9f8e8 100644 --- a/EIPS/eip-7686.md +++ b/EIPS/eip-7686.md @@ -3,7 +3,7 @@ eip: 7686 title: Linear EVM memory limits description: Adjust memory limits and gas limits of sub-calls to create a clear linear bound on how much total memory an EVM execution can consume author: Vitalik Buterin (@vbuterin) -discussions-to: https://ethereum-magicians.org/t/eip-linear-evm-memory-limits/19448 +discussions-to: https://ethereum-magicians.org/t/eip-7686-linear-evm-memory-limits/19448 status: Draft type: Standards Track category: Core From f719fb5cd0fabc213f10a2b11e2d22fb75b955ba Mon Sep 17 00:00:00 2001 From: vbuterin Date: Thu, 18 Apr 2024 11:53:58 +0200 Subject: [PATCH 4/4] Update EIPS/eip-7686.md Co-authored-by: g11tech --- EIPS/eip-7686.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7686.md b/EIPS/eip-7686.md index 9e4dd5f6e9f8e8..cae72554596f67 100644 --- a/EIPS/eip-7686.md +++ b/EIPS/eip-7686.md @@ -31,7 +31,7 @@ memory_cost = (memory_size_word ** 2) / 512 + (3 * memory_size_word) To: -``` +```python memory_size_word = (memory_byte_size + 31) / 32 memory_cost = 3 * memory_size_word ```