Skip to content

Commit

Permalink
Incorporate @xinbenlv review (ethereum#5599)
Browse files Browse the repository at this point in the history
  • Loading branch information
gcolvin authored and nachomazzara committed Jan 13, 2023
1 parent b328ed1 commit b6cedd3
Showing 1 changed file with 15 additions and 15 deletions.
30 changes: 15 additions & 15 deletions EIPS/eip-2315.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
eip: 2315
title: Simple Subroutines for the EVM
description: Two opcodes for static, safe and efficient subroutines.
description: Two opcodes for efficient, safe, and static subroutines.
author: Greg Colvin (@gcolvin), Greg Colvin <[email protected]>, Martin Holst Swende (@holiman), Brooklyn Zelenka (@expede), John Max Skaller <[email protected]>
discussions-to: https://ethereum-magicians.org/t/eip-2315-simple-subroutines-for-the-evm/3941
status: Draft
Expand All @@ -13,19 +13,19 @@ requires: 3540, 3670, 4200

## Abstract

This proposal provides a _complete_, _static_, _safe_ and _efficient_ control-flow facility.
This proposal provides a _complete_, _efficient_, _safe_ and _static_ control-flow facility.

It deprecates `JUMP` and `JUMPI`.

It depends on the two opcodes proposed by [EIP-4200](./eip-4200.md):
It depends on the two new opcodes proposed by [EIP-4200](./eip-4200.md):
* `RJUMP relative_offset` — relative jump to `PC + relative_offset`
* `RJUMPI relative_offset` — conditional relative jump

It introduces two opcodes to support calling and returning from subroutines:
It introduces two new opcodes to support calling and returning from subroutines:
* `RJUMPSUB relative_offset` -- relative jump to subroutine
* `RETURNSUB` -- return to `PC` after most recent `RJUMPSUB`.

In concert with [EIP-3540](./eip-4200.md) and [EIP-3670](./eip-3670.md) it ensures, at initialization time, that valid code will not execute invalid instructions or jump to invalid locations, will not underflow stack, will maintain consistent numbers of inputs and outputs for subroutines, and will have bounded stack height in the absence of recursion.
In concert with [EIP-3540](./eip-3540.md) and [EIP-3670](./eip-3670.md) it ensures, at initialization time, that valid code will not execute invalid instructions or jump to invalid locations, will not underflow stack, will maintain consistent numbers of inputs and outputs for subroutines, and will have bounded stack height in the absence of recursion.

Valid code will support streaming, one-pass, and other near-linear compilers.

Expand All @@ -38,28 +38,28 @@ This is among the simplest possible proposals that meets these requirements.
Jumps, conditional jumps and subroutines were proposed by Alan Turing in 1945 as a means of organizing the logic of the code and the design of the memory crystals for his Automatic Computing Engine:
> "We wish to be able to arrange that sequences of orders can divide at various points, continuing in different ways according to the outcome of the calculations to date... We also wish to be able to arrange for the splitting up of operations into subsidiary operations... To start on a subsidiary operation we need only make a note of where we left off the major operation and then apply the first instruction of the subsidiary. When the subsidiary is over we look up the note and continue with the major operation."
>
> — Alan Turing — in B.E. Carpenter, R.W. Doran, "The other Turing machine." The Computer Journal, Volume 20, Issue 3, DOI: , January 1977.
> — Alan Turing — in [B.E. Carpenter, R.W. Doran, "The other Turing machine." The Computer Journal, Volume 20, Issue 3, DOI: 10.1093/comjnl/20.3.269, January 1977.
In more contemporary terms, we have sequences of instructions, jumps and conditional jumps that divide sequences into blocks, subroutine calls, and a stack of addresses to return to. The details vary, but similar facilities have proven their value across a long line of important machines over the last 75 years, from the ACE to the Cray to the ARM.

Unlike these machines, the Ethereum Virtual Machine _does not_ provide subroutine operations. Instead, they must be synthesized using the dynamic `JUMP` instruction, which takes its destination on the stack. Further, the EVM provides _only_ dynamic jumps, impeding the static analysis we need.
Unlike these machines, the Ethereum Virtual Machine _does not_ provide subroutine operations. Instead, they must be synthesized using the dynamic `JUMP` instruction, which takes its destination on the stack. Further, the EVM provides _only_ dynamic jumps, impeding the static analysis we need.

### We need efficient control-flow.

Efficient to write by hand, compile from high level labguages, validate at deploy time, interpret by VMs, and compile to machine code.

Static jumps, conditional jumps, and subroutines are sufficient and efficient in space and time, as shown by historical experience and as we will show for the EVM below.

### We need safe control-flow.

The EVM has unusually high requirements for safety. Not only do many smart contracts control inordinately large amounts of valuable Ether, but once placed on the blockchain any defects are visible to attackers and cannot be repaired. In valid code is an We need to statically validate important safety constraints code at initialization time.
The EVM has unusually high requirements for safety. Not only do many smart contracts control inordinately large amounts of valuable Ether, but once placed on the blockchain any defects are visible to attackers and cannot be repaired. We need to statically validate important safety constraints code at initialization time.

### We need static control-flow.

The EVM's lone dynamic jumps cause two major problems. First, the need to synthesize static jumps and subroutines with dynamic jumps uses space and gas with needlessly complex code, as we will show below.

Worse, jumps that can dynamically branch to any destination in the code can cause quadratic "path explosions" when traversing the flow of control. For Ethereum, this is a denial-of-service vulnerability that prevents us, at initialization time, from validating the safe use of EVM code and from compiling EVM code to machine code.

### We need efficient control-flow.

Efficient to write by hand, compile from high level labguages, validate at deploy time, interpret by VMs, and compile to machine code.

Static jumps, conditional jumps, and subroutines are sufficient and efficient in space and time, as shown by historical experience and as we will show for the EVM below.

**We need static jumps and subroutines and must deprecate dynamic jumps.**

## Specification
Expand Down Expand Up @@ -334,7 +334,7 @@ The following is a pseudo-Python implementation of an algorithm for predicating

This algorithm performs a symbolic execution of the program that recursively traverses the _code_, emulating its control flow and stack use and checking for violations of the rules above.

It runs in time equal to `O(vertices + edges)` in the program's control-flow graph, where edges represent control flow and the vertices represent _basic blocks_thusa the algorithm takes time proportional to the size of the _code_. It uses recursion to maintain a stack of continuations for conditional jumps, the size of which is at most proportional to the size of the _code_.
It runs in time equal to `O(vertices + edges)` in the program's control-flow graph, where edges represent control flow and the vertices represent _basic blocks_thus the algorithm takes time proportional to the size of the _code_. It uses recursion to maintain a stack of continuations for conditional jumps, the size of which is at most proportional to the size of the _code_.

### Validation Function

Expand Down

0 comments on commit b6cedd3

Please sign in to comment.