diff --git a/EIPS/eip-2583.md b/EIPS/eip-2583.md index b2a67988..f521d0ea 100644 --- a/EIPS/eip-2583.md +++ b/EIPS/eip-2583.md @@ -12,11 +12,11 @@ created: 2020-02-21 ## Simple Summary -This EIP propose to introduce a gas penalty for opcodes which access the account for trie non-existent accounts. +This EIP introduces a gas penalty for opcodes which access the account for trie non-existent accounts. ## Abstract -This EIP proposes to add a gas penalty for accesses to the account trie, where the address being looked up does not exist. Non-existing accounts can be used in +This EIP adds a gas penalty for accesses to the account trie, where the address being looked up does not exist. Non-existing accounts can be used in DoS attacks, since they bypass cache mechanisms, thus creating a large discrepancy between 'normal' mode of execution and 'worst-case' execution of an opcode. ## Motivation @@ -58,22 +58,21 @@ These are the opcodes which triggers lookup into the main account trie: | Opcode | Affected | Comment | | ----- | ---------| ----------| -| BALANCE| Yes | `balance(inexistent_addr)` would incur `penalty`| -| EXTCODEHASH| Yes | `extcodehash(inexistent_addr)` would incur `penalty`| -| EXTCODECOPY| Yes | `extcodecopy(inexistent_addr)` would incur `penalty`| -| EXTCODESIZE| Yes | `extcodesize(inexistent_addr)` would incur `penalty`| +| BALANCE| Yes | `balance(nonexistent_addr)` would incur `penalty`| +| EXTCODEHASH| Yes | `extcodehash(nonexistent_addr)` would incur `penalty`| +| EXTCODECOPY| Yes | `extcodecopy(nonexistent_addr)` would incur `penalty`| +| EXTCODESIZE| Yes | `extcodesize(nonexistent_addr)` would incur `penalty`| | CALL | Yes| See details below about call variants| | CALLCODE | Yes| See details below about call variants| | DELEGATECALL | Yes| See details below about call variants| | STATICCALL | Yes| See details below about call variants| | SELFDESTRUCT | No| See details below. | -| CREATE | No | Create destination not explicitly settable, and assumed to be inexistent already.| -| CREATE2 | No | Create destination not explicitly settable, and assumed to be inexistent already.| +| CREATE | No | Create destination not explicitly settable, and assumed to be nonexistent already.| +| CREATE2 | No | Create destination not explicitly settable, and assumed to be nonexistent already.| ### Notes on Call-derivatives - A `CALL` triggers a lookup of the `CALL` destination address. The base cost for `CALL` is at `700` gas. A few other characteristics determine the actual gas cost of a call: 1. If the `CALL` (or `CALLCODE`) transfers value, an additional `9K` is added as cost. @@ -107,6 +106,17 @@ The `SELFDESTRUCT` opcode also triggers an account trie lookup of the `beneficia - The `base` costs of any opcodes are not modified by the EIP. - The opcode `SELFBALANCE` is not modified by this EIP, regardless of whether the `self` address exists or not. + +## Rationale + +With this scheme, we could continue to price these operations based on the 'normal' usage, but gain protection from attacks that try to maximize disk lookups/cache misses. +This EIP does not modify anything regarding storage trie accesses, which might be relevant for a future EIP. However, there are a few crucial differences. + + +1. Storage tries are typically small, and there's a high cost to populate a storage trie with sufficient density for it to be in the same league as the account trie. +2. If an attacker wants to use an existing large storage trie, e.g. some popular token, he would typically have to make a `CALL` to cause a lookup in that token -- something like `token.balanceOf()`. + That adds quite a lot of extra gas-impediments, as each `CALL` is another `700` gas, plus gas for arguments to the `CALL`. + ### Determining the `penalty` A transaction with `10M` gas can today cause ~`14K` trie lookups. @@ -120,20 +130,9 @@ There exists a roofing function for the `penalty`. Since the `penalty` is deduct In such a scenario, the `malicious` would spend `~750` gas each call to `relay`, and would need to provide the `relay` with at least `700` gas to do a trie access. -Thus, the effective `cost` would be on the order of `1500`. It can thus be argued that `penalty` above `~800` would not achieve better protection against state-inexistence attacks. +Thus, the effective `cost` would be on the order of `1500`. It can thus be argued that `penalty` above `~800` would not achieve better protection against trie-miss attacks. -## Rationale - -With this scheme, we could continue to price these operations based on the 'normal' usage, but gain protection from attacks that try to maximize disk lookups/cache misses. -This EIP does not modify anything regarding storage trie accesses, which might be relevant for a future EIP. However, there are a few crucial differences. - - -1. Storage tries are typically small, and there's a high cost to populate a storage trie with sufficient density for it to be in the same league as the account trie. -2. If an attacker wants to use an existing large storage trie, e.g. some popular token, he would typically have to make a `CALL` to cause a lookup in that token -- something like `token.balanceOf()`. - That adds quite a lot of extra gas-impediments, as each `CALL` is another `700` gas, plus gas for arguments to the `CALL`. - - ## Backwards Compatibility This EIP requires a hard-fork.