No need for exception handling in contract code?


There is no concept of exceptions in CLL. Correct?
What happens if something goes wrong?
Is there no need to cope with unexpected situations?

Only the usual "if tx.value < ...." that's it?

Comments

  • chris613chris613 Member Posts: 93 ✭✭
    Exception handling should not be necessary in this VM. Exceptions in programming are generally related to resource reservation or I/O . "We tried to do X, but failed" where X is something like reserving memory, accessing a network, reading from a disk, or generally anything other than simply executing CPU instructions (multiplying, substracting, jumping, register access, etc).

    In EVM3 there is no IO outside the VM, so exceptions could only occur while trying to do memory operations such as operating on the stack and loading or storing values in memory or storage. These calls never fail, though. You don't make a request to allocate memory, you just use the address, any address, they are all valid. The resource is assumed to always be there. The stack always works. Storage is always available.

    Now of course, in reality sometimes it WILL fail. The miner running the contract will run out of actual memory on their system, and you won't be able to store, or some value in your contract's storage is cached on a disk drive that fails, so you fail to read. These will generate exceptions in the EVM that propagate up through libethereum to your client software to be reported. There is no reason at all to make this visible to the internals of a contract, though, because only 1 miner is experiencing this failure, many more will not have run out of resources and will agree on the new state that is the outcome of the contract running exception free.

    I hope that makes sense.
  • romanixromanix Member Posts: 10
    Thanks for the explanation. It makes sense - at the same time it sounds like too good to be true ;-)
  • yoyoyoyo Member Posts: 34 ✭✭
    There are plenty of ways to get exceptions in pure code. Division by 0, negative index, etc.

    The usual way around that is to write programs in a defensive way and check the exceptional conditions before running the actual code. We will definitely need tools to test contracts thoroughly before they go live.
  • chris613chris613 Member Posts: 93 ✭✭
    @yoyo? is right. I said that exceptions "are generally related to resource reservation or I/O", but certainly given a more complex VM or a hardware CPU there can be pure code that will cause a run-time exception. Generally (there's that word again!) these exceptions are propagated up to the OS running on the machine via an interrupt that causes a branch to a pre-defined handler which usually terminates the offending process and might pop up a window to let you know. There is definitely none of this in the EVM. I've just read the latest source code, and while there is nothing that allows you to catch these classes of errors from within your contract code, here is what I can tell you about the two examples given (+ a bonus).

    Divide by zero: There is a check for this on the DIV, SDIV, and MOD instructions and all of them simply cause the contract to terminate.

    Negative indexes: Values used for storage access and as indexes to the memory region are unsigned, so at the VM level there is no such thing as a negative index. You may have a logic error in your code, but it will not cause an exception. Access to transaction data is similar, with the difference that if your index is out of range it simply returns 0.

    Another one is sending more ether than you have. In this case a c++ exception is actually generated in the VM code and caught higher up the stack. Again the contract will terminate. Many contracts can guard against this with popular idiom "if tx.value < tx.basefee * SOMETHING: exit" at the start of the code. More complex contracts might want to check their balance before each call to mktx if they would like to recover from a NSF condition.

    While it would be nice if the EVM implemented some sort of post-facto handler for these types of runtime exceptions, the cases are so trivial and well defined that the code to check for the exceptional conditions before calling the functions is no more arduous to write than the equivalent exeption handling code would be. The benefit of doing it this way is a simpler VM, which IMO is probably the right tradeoff at this point in the project.

Sign In or Register to comment.