EIP-615: Subroutines and Static Jumps for the EVM

evm

#1

This proposal is first of all about deprecating dynamic jumps, which play hell with formal specs, proofs of correctness, static analysis, optimizing compilation, and a lot more. And being rid of them, introducing subroutines and a few other operations to replace them. This gives an immediate benefit in formal tractability, and opportunities for increased performance.
EIP-615: Subroutines and Static Jumps for the EVM

I’m incorporating changes for later PRs into the original proposal.


#2

@AlexeyAkhunov @androlo @Arachnid @axic @boris @cdetrio @chfast @chriseth @Ethernian


#3

@expede @fubuloubu @fulldecent @grosu @gumb0 @holiman @karalabe @lrettig @mattlock @tjayrush


#4

@vbuterin
@<others I’m forgetting whose judgment I value, or should>
(you can only mention 10 people in a post)


#5

(Typing from a phone… sorry for short post. Infer detail as needed :sweat_smile:)

I would maybe put a bit more nuance on it: this proposal introduces structured control flow, which makes it MUCH easier to analyze smart contracts for correctness, security considerations, and for the EVM to performance optimize (doesn’t matter JIT or AOT), and do gas meter aggregation.

Deprecating dynamic jumps is an excellent step in driving users to more structured flow by default. There are legitimate uses of dynamic jumps, but they’re FAR into the realm of edge cases.

As part of a broader strategy (what @boris and I have been calling “EVM Evolution”), this is the first step towards a much safer & faster EVM. Ewasm is still coming, but we should improve the EVM that we have today. This change also makes it easier to port code to wasm when the day comes.

I’ve spoken with a number of mainstream client implementers at Devcon IV and Standford, and these changes sound fairly uncontroversial so far. We would love as much feedback on this proposal as possible ahead of moving this proposal to Last Call!

Thanks everyone :grin::grin::grin:


#6

Thank you! The reason I am interested in this is potential for more efficient concurrent execution of transaction. Provided that if the Ethereum state keeps growing at least for next couple of years, we have started exploring the ideas of storing parts of the state remotely and fetching them in batches during the execution. I have done some crude modelling here, but realised very quickly that static analysis might be used together with symbolic execution to elide locks during such executions. Any concrete hints in that direction?


#7

Thanks @AlexeyAkhunov. That’s a difficult read that will take me a cup of coffee here as the sun rises. Could say more about how symbolic execution would help this scheme? I suspect @expede might even understand you!


#8

So yes, while it really isn’t possible to get rid of dynamic jumps since they are used so heavily in current EVM programs, I would say most languages could move users over to that if a static jump option were available that was sufficiently cheap (and it should be cheaper than a dynamic jump because of how much more optimizable it would be for program flow, data loading, etc)

Vyper has spoken very positively about this proposal, and as a smaller, security-focused language we would have no problems deprecating the use of dynamic jumps entirely. However, I don’t think that would be possible for a larger, more powerful language that opens up to assembly instructions like Solidity, but it would be good enough if the higher level language were able to make the switch for all internal calls, which certainly seems plausible.


#9

P.S. is there any chance that subroutines can be considered separately?


#10

A static jump is O(1). A dynamic jump takes a binary search of a table of every JUMPDEST in the program. So O(1) vs O(log n) to start with, even before low-level optimizations.


#11

Get rid of dynamic jumps and how to construct subroutines?


#12

No I mean to put this proposal into stages and reduce implementation risk.

  1. Add subroutines
  2. Add static jump opcodes
  3. Work on community education and reducing the prevalence of dynamic jump usage

#13

Would also be good to get a survey of dynamic jump usage, I’m not exactly sure how prevalent it is or how many different ways it is used


#14

Deprecating just means that validation will reject Solidity programs that attempt to meet the new standard. Whether a means for new code to bypass validation is maintained indefinitely will get determined after the 1st phase of optional validation.


#15

Every return from a subroutine in Solidity requires a dynamic jump.


#16

Is that the only use? Do people develop in assembly alternative uses? Where’s the usage data?


#17

Dynamic jumps also used for switch statements and virtual functions, and could be used in lots of creative ways in assembly code, I suppose. I’m not too concerned about placing a bit of a burden on creative assembly coders in return for better high-level code generation.


#18

I just want to make sure we don’t miss a geniune use case in our mission to salt the earth of dynamic jumps (sarcasm mine)


#19

Thus the call for introduction in two phases. We can make validation optional if need be, but I’m not sure I’ve ever seen the use of unconstrained dynamic jumps in programs for other CPUs. Or even an unconstrained dynamic jump instruction (and please someone correct me.)


#20

Yes, they could be split into 2 (or 3) EIPs. I feel that this would be cleaner as well. I brought this up a while back, and the prevailing feeling was that since this EIP already has momentum, just let it be. TL;DR yes, but no for political reasons.

Also, I don’t think that any of these features are controversial. Let’s just get them into the spec.