ethereum/EIPs

New opcode: REVERT ("cheap throw")

nmushegian opened this issue · 13 comments

  EIP:
  Title: Opcode for exceptions that don't drain gas
  Author: Nikolai Mushegian (nikolai@nexusdev.us)
  Discussions-To: 
  Status: Draft
  Type: Standards Track
  Created:
  Replaces:
  Superseded-By:
  Resolution:

I tried to find an existing EIP for this and couldn't. This surprises me! Please help find existing discussion.

Abstract

Right now rolling back state requires manually triggering an EVM exception (eg invalid jump), which drains all gas for the subcall. I prefer throw-oriented error handling despite all the drawbacks (no error details, drains gas) because reverting all state when something unexpected happens feels much safer.

The REVERT opcode would let you throw an exception without draining all the gas that the caller allocated to you.

Related issues:
#62
ewasm/design#43

Details

Extra things to consider

  • Per #62, it would be useful to be able to pass back a return value to be interpreted as an error when an exception is thrown. Solidity already re-throws when the stack is 0 so this backwards compatible in terms of Solidity semantics but may not be if someone has done ASM hacking where they read the "return". This is a nice-to-have, if it can't be done than a simplified version which gives you back no useful information is still much better than "deliberate invalid jump".
axic commented

@nmushegian the reason we haven't pushed ewasm/design#43 to an EIP yet is because it involves a lot more than just including a new opcode.

What specifically? I understand that proposal has additional functionality, but I don't understand why just this request is a lot more than adding a new opcode for a simple version of "deliberate invalid jump".

I edited OP to clarify that getting return data out (ie doing anything but invoking the existing exception mechanism) is a nice-to-have, likely out of scope for evm 1.x

I'd support this; I also don't see why we can't just reuse the existing call return data mechanism for exception return data. It's only a 2 line of code change once the opcode exists (at least in pyethereum).

axic commented

@nmushegian: I'm getting a bit confused. Are you proposing an opcode which stops execution, returns a reason, doesn't revert state and doesn't drain gas? Or something that behaves like the current exceptions and reverts state?

Are you proposing an opcode which stops execution, returns a reason, doesn't revert state and doesn't drain gas? Or something that behaves like the current exceptions and reverts state?

Not return a reason, since that would require much more significant VM changes. Simply revert state (and put a 0 instead of a 1 on the caller's stack) like the current exception mechanism, but don't drain all the gas.

axic commented

@nmushegian thanks! Can you please update the original description with this?

I would propose the name REVERT, as ABORT usually (in C land for example) doesn't ensure that everything is in a consistent state, it rather stops as is.

Done, REVERT is better

+1 - love this idea

I didn't realize the standard exception mechanism doesn't roll back suicides! This is very not intuitive! https://www.reddit.com/r/ethereum/comments/5hiy29/solidity_throw_after_selfdestruct_why_does_the/

Maybe REVERT could use the behavior we expect?

edit: Turns out that was just an error in just one of the implementations

axic commented

If we assume REVERT has its own cost, but won't consume all the remaining gas, we could consider to make it a bit similar to RETURN in the sense in takes the top two stack items as a memory pointer and length. It would have the same cost as RETURN.

That way complex error reporting could be implemented.

Additionally, if REVERT runs out of gas, you end up with a regular OOG case. Essentially you only lose the error reporting.

I agree with @axic in that this is a good time to integrate error reporting. I initially thought this could be done informally by simply leaving values on the stack at throw, but this only allows debugger inspection of error codes, and also makes propagating errors difficult. If revert allows return data, we can properly report error codes to callers.

axic commented

Created an actual draft out of this, see #206.

Closing issue as @axic has begun the formal EIP process at #206.