EIP-615: Subroutines and Static Jumps for the EVM -- Last Call

@fubuloubu tells me the Vyper project (or at least he) is in support. As I recall it the Solidity team added hooks for at least the primitive opcodes into Yul. I think some degree of support was added to Solidity as well. @axic would know.

@shemnon I just checked the source. Yul and Solidity have hooks (defined opcodes and empty code generation functions) for the eventual implementation of this proposal. @axic or @chriseth would know how much work remains.

We moved from internal calls to dynamic jumps for gas savings within our contracts and have had nothing but problems with it. This proposal would be very helpful, as it would allow us to get the safety we need while saving gas, which is what lead us to make that decision.

A quick note here: EIP-1380: Reduced gas cost for call to self would also help achieving that by using the old system for calls in Vyper.

1 Like

The Yul assembler has support for a version of EIP615 from 2 years ago. No recent changes are applied. Back when it was implemented there were no decision on the size of the immediate. The output of the assembler was never tested given there is no testing environment for it.

Solidity to Yul is still progress, so there is no complete support for Solidity to EVM615.

Solidity has zero support for this. Many internal routines of the code generator would have to be rewritten or at least modified.

There is support for compiling Yul to something like this proposal, but it is completely untested. Furthermore, we are currently working on a full rewrite of the code generator to target Yul. Once that is finished, we can compile to both web assembly and execution environments that require static jumps, but this will still take several months.

In general, I strongly oppose this proposal in its current form. I think the introduction of multi-byte opcodes is dangerous and in general, it is a big change to EVM implementations.

The proposal was initially written with speedup in mind and not with easy of verification. The speedup turned out to be not really present, Pawel’s evmone implementation seems to be a much better solution.

I do not see the benefit of ease of verification worthwhile when compared to the risk of radical changes to the EVM, especially as implementations still need to keep both implementations. If code is analyzed, symbolic execution has to be performed in any case. In most situations, this can easily resolve the jump targets even when they are taken from the stack. At least when compiled from Solidity, the situations where this is difficult will still remain: The only situation where the jump target is not directly available on the stack is when function types are used. These function types would still need a dispatch table, so the problem is not really solved. The benefit of a dispatch table over dynamic jumps is of course that the set of potential targets is smaller. I would say that this set can already be restricted in the current EVM by analyzing how many elements on the stack are accessed by a routine, how many elements are returned and similar techniques. Furthermore, additional output from the compiler can also be used to improve the analysis - the compiler knows which jumpdest is dynamic and which is not. Unless when jump targets are read from storage (and maybe even then!), a formal system should be able to verify the correctness of this information to guard against compiler bugs.

In closing, I think this is a problem that should be solved above the EVM. It is a big risk to modify the EVM implementations and also the Solidity code generator to conform to it. Even when this proposal is implemented, malicious code can still run the old way, so this can only be a protection against bugs and not against bad intent. If it is just about finding bugs, we should have access to the source code and can use the help of the compiler and other tools. Furthermore, instead of adapting Solidity’s “legacy” code generator, I would prefer to focus on the re-implementation that uses Yul. The code that is generated from Yul will already use a dispatch table instead of dynamic jumps and it should be rather straightforward to resolve all jump destinations.

1 Like

Thanks for the feedback @chriseth. Most of it would have been more helpful when you co-authored this proposal in 2016. By now it is simply too late to change the form of this proposal–it would amount to abandoning the proposal, probably permanently. The best I can do now to simplify it would be to stick to the primitive operations and eliminate JUMPV, JUMPSUBV, GETLOCAL, and PUTLOCAL.

Improving the tractability of formal analysis of EVM code was a desiderata from the start. (See link to original proposal below.) The performance gains were to be had by facilitating near-linear-time compilation, in the same way that Wasm compilers like Lightbeam take advantage of its clean control flow to that end. My measurements indicate that evmone is about twice as fast as aleth, and my study of the code indicates that this is primarily because it implements optimizations that you decided not to pay me to implement for aleth back in 2017. It’s true that those optimizations do not depend on this proposal.

1 Like

Please, let’s keep the discussion technical and not personal.

Thank you, @shemnon. And my apologies, @chriseth.

@chriseth has expressed very belated but very strong and reasoned objections to EIP-615. Being as he is a core developer and coauthor of the proposal I must take it that there is not consensus to move forward. I am withdrawing the proposal from further consideration.

1 Like

Given the open and egalitarian nature of the community, I don’t see a problem with people explaining that lack of payment results in lack of implementation. No one is mocking anyone.

1 Like

I’de spend more time on this but I am involved in putting a bow on what is finally in the Istanbul so my priorities lie elsewhere. I think that the ideas in this EIP are worth working on and if things go as planned I may come back to this by the end of the year, possibly in several smaller EIPs.

To that end two things are worth pointing out. First: my advocacy for getting EIP-1702 was preparatory for EVM upgrades like in this EIP. The radical changes would not leak into older versions of contracts. There is also some recommended methods to allow for multiple versions on the chain at the same time.

Second the argument that multi-byte instructions don’t already exist is not entirely accurate. All of the push instructions keep immediate mode values in the code. While they do not directly impact EVM execution they often do in the next instruction, when a jump is called. We can split hairs over the semantics but push <x> jump isn’t much different from jumpto <x>, whereas with the latter we can deprecate dynamic jumps (and then get linear time native compilation, and then eliminate the need for random precompiles for performance reasons).

@chriseth proposed that “additional output” and “a formal system” can be used to to gain the same benefits. Saying there are better ways to do without a concrete implementation is letting perfect be the enemy of better. If there are better solutions they should be proposed so they can be implemented. Until then this is the best solution that I’ve seen proposed to get the EVM to adopt modern VM technologies and thus reap the benefits (such as linear time native compilation).

1 Like

My snark was out of line by my own standards, @AFDudley, and I’m glad that @shemnon called me out on it.

I’ll be happy to help with this, but it unlikely I can be a champion again. I will likely be editing the EIP soon to lay out a better backwards compatibility plan to implement this in stages–amounting perhaps to a few EIPs, but better maintaining conceptual integrity and a clear path forward. So we should stay in touch on this, @shemnon. I think a successful reintroduction of this proposal would take a more up-to-date reference implementation, test vectors, support by at least one high level language, and an explicit push from the formalists, auditors, and tool makers who have expressed private support. @expede, @boris, and myself attempted to get EF funding for that work, but were denied for reasons unknown.

I was trying to get the EVM architecture up to the standards of 1950’s era stack machines, so not all that modern.

1 Like

@boris, I should add that like you and Brooke I would be loathe to work with the Ethereum Foundation on any future project. Their grants process is dysfunctional, unprofessional, and unfair to proposers. They also offer about 1/2 to 1/4 of the going rate for senior American engineers, or less. Volunteering what time I can I will do.

1 Like

I don’t have much issue with their rates. It’s a “break even” level of compensation that won’t build sustainable teams but does compensate engineers that want to do some public service.

Wasting 7 months of our time without clear feedback and then having the EVM Working Group being the only funding not approved with the personal attack of “someone at the EF doesn’t like Boris” is the issue.

The EVM evolution roadmap is there if people care about making a better VM today that leads to a better / easier transition to a future WASM EE is there if people want to follow it.

2 Likes

The rate issue depends a lot on where you live and what you could otherwise earn. Ethereum is not a charity, though I’ve treated it like one. Ethereum is a community, but not yet a self-sustaining one. So now I need to earn what I’m worth as as senior VM architect, and get my R&D back on the cutting edge.

And yes, “dysfunctional, unprofessional, and unfair to proposers.” You were treated shabbily.

I think things will be picked up again, but the need will have to be more apparent. The test will be whether we can write an EVM compiler that can’t go quadratic in the face of adversarial code.

1 Like

The lead author here has confirmed to withdraw the proposal from further consideration in this round. So now wanted to add non-technical notes.

On the human side. I consider this review/discussion to be a success. Having just some of the attention of the great people in this room is value enough for me to get involved in these reviews and bring my a-game.

Private support is a real thing. Many of the use cases (people that want to use the new things that get invented here) will reach out privately. If you spend a lot of time on GitHub and have never put your phone number/email directly in an issue then you might not know really how many not-GitHub people are reading along. These are great relationships, they lead to good, profitable client relationships.

Now is a good time to regroup and follow up on any new contacts we made along the way in this journey. Wishing all the best.

2 Likes

Thank you @fulldecent. We sometimes disagree technically, but always in a civilized manner. My Magicians, Github, and Twitter profiles include my email address, so I’m easy to find, and have done good work with people who have found me. It is unfortunate that many of the people supporting this proposal did not make their needs more clear in our public forums. It’s also unfortunate that I withdrew the proposal not for technical reasons, but because @chriseth–a major coauthor–objected. I have asked him to remove his name from the proposal so that any future attempt to introduce this proposal by @shemnon or others can be judged mainly on technical grounds.

Actually, the proposal points at nearly complete C++ code for an earlier version of the proposal, in the aleth repo. Not that much has changed, so it still serves as useful example.