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

Update EIP-7620: Initcode mode validation #8586

Merged
merged 3 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 16 additions & 7 deletions EIPS/eip-7620.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Details on each instruction follow in the next sections.
- check that current call depth is below `STACK_DEPTH_LIMIT` and that caller balance is enough to transfer `value`
- in case of failure return 0 on the stack, caller's nonce is not updated and gas for initcode execution is not consumed.
- caller's memory slice [`input_offset`:`input_size`] is used as calldata
- execute the container in "initcode-mode" and deduct gas for execution. The 63/64th rule from [EIP-150](./eip-150.md) applies.
- execute the container and deduct gas for execution. The 63/64th rule from [EIP-150](./eip-150.md) applies.
- increment `sender` account's nonce
- calculate `new_address` as `keccak256(0xff || sender || salt || keccak256(initcontainer))[12:]`
- an unsuccesful execution of initcode results in pushing `0` onto the stack
Expand All @@ -82,8 +82,6 @@ Details on each instruction follow in the next sections.
- if updated deploy container size exceeds `MAX_CODE_SIZE` instruction exceptionally aborts
- set `state[new_address].code` to the updated deploy container
- push `new_address` onto the stack
- `RETURN` and `STOP` are not allowed in "initcode-mode" (abort execution)
- "initcode-mode" *is not transitive* - it is only active for the frame executing the initcontainer. If another (non-create) call is made from this frame, it *is not* executed in "initcode-mode".
- deduct `GAS_CODE_DEPOSIT * deployed_code_size` gas

#### `RETURNCONTRACT`
Expand All @@ -93,16 +91,27 @@ Details on each instruction follow in the next sections.
- cost 0 gas + possible memory expansion for aux data
- ends initcode frame execution and returns control to EOFCREATE/4 caller frame where `deploy_container_index` and `aux_data` are used to construct deployed contract (see above)
- instruction exceptionally aborts if after the appending, data section size would overflow the maximum data section size or underflow (i.e. be less than data section size declared in the header)
- instruction exceptionally aborts if invoked not in "initcode-mode"

### Code Validation


For terminology purposes, the following concepts are defined:

- an "initcode" container is one which does not contain `RETURN` or `STOP`
- a "runtime" container is one which does not contain `RETURNCONTRACT`

Note a container can be both "initcode" and "runtime" if it does not contain any of `RETURN`, `STOP` or `RETURNCONTRACT` (for instance, if its code sections terminate with `REVERT` or `INVALID`).

We extend code section validation rules (as defined in [EIP-3670](./eip-3670.md)).

1. `EOFCREATE` `initcontainer_index` must be less than `num_container_sections`
1. `EOFCREATE` the subcontainer pointed to by `initcontainer_index` must have its `len(data_section)` equal `data_size`, i.e. data section content is exactly as the size declared in the header (see [Data section lifecycle](#data-section-lifecycle))
2. `RETURNCONTRACT` `deploy_container_index` must be less than `num_container_sections`
3. `RJUMP`, `RJUMPI` and `RJUMPV` immediate argument value (jump destination relative offset) validation: code section is invalid in case offset points to the byte directly following either `EOFCREATE` or `RETURNCONTRACT` instruction.
2. `EOFCREATE` the subcontainer pointed to by `initcontainer_index` must have its `len(data_section)` equal `data_size`, i.e. data section content is exactly as the size declared in the header (see [Data section lifecycle](#data-section-lifecycle))
3. `EOFCREATE` the subcontainer pointed to by `initcontainer_index` must be an "initcode" subcontainer
4. `RETURNCONTRACT` `deploy_container_index` must be less than `num_container_sections`
5. `RETURNCONTRACT` the subcontainer pointed to `deploy_container_index` must be a "runtime" subcontainer
6. It is an error for a container to contain both `RETURNCONTRACT` and either of `RETURN` or `STOP`
7. It is an error for a subcontainer to never be referenced in code sections of its parent container
8. `RJUMP`, `RJUMPI` and `RJUMPV` immediate argument value (jump destination relative offset) validation: code section is invalid in case offset points to the byte directly following either `EOFCREATE` or `RETURNCONTRACT` instruction.

### Data Section Lifecycle

Expand Down
8 changes: 2 additions & 6 deletions EIPS/eip-7698.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,21 @@ In case a creation transaction (transaction with empty `to`) has `data` starting

1. Intrinsic gas cost rules and limits defined in [EIP-3860](./eip-3860.md) for creation transactions apply. The entire `data` of the transaction is used for these calculations.
2. Find the split of `data` into `initcontainer` and `calldata`:

- Parse EOF header
- Find `intcontainer` size by reading all section sizes from the header and adding them up with the header size to get the full container size.

3. Validate the `initcontainer` and all its subcontainers recursively.

- Unlike in general validation, `initcontainer` is additionally required to have `data_size` declared in the header equal to actual `data_section` size.

- Validation includes checking that the container is an "initcode" container as defined in [EIP-7620](./eip-7620.md), that is, it does not contain `RETURN` or `STOP`
4. If EOF header parsing or full container validation fails, transaction is considered valid and failing. Gas for initcode execution is not consumed, only intrinsic creation transaction costs are charged.
5. `calldata` part of transaction `data` that follows `initcontainer` is treated as calldata to pass into the execution frame.
6. Execute the container in "initcode-mode" (see [EIP-7620](./eip-7620.md)) and deduct gas for execution.
6. Execute the container and deduct gas for execution.
1. Calculate `new_address` as `keccak256(sender || sender_nonce)[12:]`
2. A successful execution ends with initcode executing `RETURNCONTRACT{deploy_container_index}(aux_data_offset, aux_data_size)` instruction. After that:
- load deploy-contract from EOF subcontainer at `deploy_container_index` in the container from which `RETURNCONTRACT` is executed,
- concatenate data section with `(aux_data_offset, aux_data_offset + aux_data_size)` memory segment and update data size in the header,
- let `deployed_code_size` be updated deploy container size,
- if `deployed_code_size > MAX_CODE_SIZE` instruction exceptionally aborts,
- set `state[new_address].code` to the updated deploy container.
3. `RETURN` and `STOP` are not allowed in "initcode-mode" (abort execution)
7. Deduct `200 * deployed_code_size` gas.

## Rationale
Expand Down
Loading