Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-2677: Cap initcode (draft) #2677

Merged
merged 7 commits into from
Aug 29, 2020
Merged
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions EIPS/eip-2677.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
eip: 2677
title: Limit size of `initcode`
author: Martin Holst Swende (@holiman), Pawel Bylica (@chfast), Alex Beregszazi (@axic)
discussions-to: https://ethereum-magicians.org/t/eip-2677-limit-size-of-initcode/4550
status: Draft
type: Core
created: 2020-05-18
---

## Simple Summary

Enforce a maximum size limit (`max_initcode_size`) of `49152` (`0xc000`) for `initcode`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Enforce a maximum size limit (`max_initcode_size`) of `49152` (`0xc000`) for `initcode`.
Set a maximum size limit of 49152 for `initcode`.


## Abstract

Enforce a maximum size limit (`max_initcode_size`) for `initcode`. If the size of `initcode` exceeds `max_initcode_size`, then contract creation fails with an out of gas error.

Since [EIP-170](https://eips.ethereum.org/EIPS/eip-170) was implemented, there has been a size limit of `24576` (`0x6000`) on contract code. We propose to also limit the size of executable code to `2x` the above limit, i.e. `49152` (`0xc000`).

This also leads to two nice properties:

- instruction offset in code fits 16-bit value,
- code size fits 16-bit value.
Comment on lines +20 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving all of this to the motivation section. Abstract should be a human-friendly and terse version of the specification, while the motivation section is where you state why this is a good idea, how these changes make things better, etc.


## Motivation

When a client executes `initcode`, the client has to perform a jumpdest analysis. In some cases, the client also performs a `hash` of the code:

* To use as a key in a mapping containing result of a jumpdest analysis
* To use for address calculation within `CREATE2`.

The work performed during a jumpdest analysis scales linearly with the size of the code. Currently, a transaction can expand the memory once, and reuse the same memory segment (with minor modifications) to force the client to perform a lot of analysis/hashing, leading to slow block processing.

Historically, this was exploited in June 2017, precipitating the 1.6.5-patch release of [geth](https://github.com/ethereum/go-ethereum/releases/tag/v1.6.5)

The work performed during address calculation within `CREATE2` is charged in proportion with size of the code.

## Specification

There are three situations where this is applicable:

* `CREATE`,
* `CREATE2`,
* creation using a transaction with empty receiver.

In all these (and future) cases, the EVM should fail with Out Of Gas error if the code has a length more than `max_initcode_size`.
Comment on lines +40 to +48
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A user should be able to implement an EIP from the specification section alone. Currently, this specification section is not self contained as it appears to be referring to information in other sections (e.g., the this reference in the first sentence).

Also it should make assertions, not suggestions, especially for consensus code. "should fail" will result in total consensus failure if some clients fail and some clients don't fail. My guess is that you meant MUST fail here.

Also, the specification section should not be discussing hypothetical future cases here. It may be worth mentioning in the security considerations or backward compatibility section, but discussion about the behavior of future hypothetical cases are not really relevant for the specification section of a technical document.


## Rationale

TBA

## Backwards Compatibility

This EIP requires a "network upgrade", since it modifies consenus-rules.

## Security Considerations

For client implementations, this EIP makes attacks based on jumpdest-analysis or hashing of code less problematic, so should increase the robustness of clients.

For layer 2, this EIP introduces failure-modes where there previously were none. There _could_ exist factory-contracts which deploy multi-level contract hierarchies, such that the code for multiple contracts are included in the initcode of the first contract. The author(s) of this EIP are not aware of any such contracts.

## Test Cases

Test cases should include the following cases,

- `CREATE`/`CREATE2`/`tx create` with `initcode_size` at `max_initcode_size`
- `CREATE`/`CREATE2`/`tx create` with `initcode_size` at `max_initcode_size+1`

## Implementation

TBA

## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).