-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change effect of assert to invalid opcode. #1702
Conversation
This might need also updates for the tests. |
This will break the possibility to return the assert reason as a text, because that is only possible via |
@pirapira this might also be of interest to you. |
@chriseth for me, it's fine if assertion failures are translated into 1) the invalid opcode, or 2) REVERT with data somehow saying "assertion failure". |
docs/control-structures.rst
Outdated
(or at least call) without effect. | ||
|
||
If contracts are written so that ``assert`` is only used to test internal conditions and ``throw`` or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The phrase "internal conditions" might not make sense to everyone. What about "If contracts are written so that assert
should never fail at runtime."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to convey when to use assert
and when to use throw
. How would you write that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An assert
should be a sanity check that is expected to pass always. An assert
failure should detect coding mistakes (e.g. when the owner of something has changed without the owners' permission).
throw
should catch everything else that goes wrong at runtime (e.g. when the caller supplies wrong data; it's not time yet to call this function).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chriseth @pirapira Maybe it would be helpful to explain who is responsible for ensuring that there are no such exceptions: "assert
is used to express safety conditions that the contract should ensure. Consequently, the author of the contract is responsible for avoiding any assertion violations. In contrast, throw
can be used to express that some input is not considered valid. It is the responsibilty of the client/caller, as opposed to the contract's author, to ensure that this does not happen. Formal analysis tools can be used to verify that no execution of a contract leads to an assertion violation assuming the client/caller provided valid inputs.".
Does that capture what you want to express?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wuestholz yes, that sounds accurate. Thank you.
@pirapira indeed. I think in the end we perhaps need two different asserts. |
@chriseth @pirapira @axic I don't think two different asserts are necessary. I tried to elaborate on the difference in a comment above. In my opinion, an assertion violation should be "blamed" on the author of the contract where the violation happened. The client/caller of the contract shouldn't need to know about all the possible things that may go wrong (e.g., division by zero) in the callee contract. In contrast, an exception that is thrown is similar to a precondition violation. The client/caller should be "blamed" in this case and should be given a chance to react by providing a different input or by propagating the exception up the call stack. In short, use a In a nutshell, this is the main idea behind Design by Contract (https://en.wikipedia.org/wiki/Design_by_contract). |
@wuestholz yes, this is also what I currently have in mind. The question is whether we want to shorten |
Then we can have
Assertions can be defined in a library, so they do not need to be defined in the language. |
@chriseth @pirapira Great that we seem to agree on the semantics. :) Now about the syntax: I agree that one could define such things as a library. However, I think chances are higher that people make use of this if the language supports it natively. Given my background in program analysis Assertions should be familiar to most programmers and I don't see a reason to reinvent the wheel here. However, most programmers will not be familiar with assume-statements. Maybe something like Another reason for such native language support is that tools can extract such conditions more easily (e.g., to generate documentation that includes preconditions for procedures). |
"Decision" of team meeting: Remove the global assert function for the next release. After that, we will have
The actual naming of 2 and 3 has to be discussed. |
9f92349
to
4b1e811
Compare
@chriseth Thank you for the update! Please let me know if you would like my input once you're ready to design the changes for the next release. I'm very interested in finding a good solution for these issues and would be glad to help. |
Can we roll back the first commit? The second commit also needs to adjust the changelog. Then again if we make a decision on naming on Tuesday/Wednesday, we might as well keep this PR open until that point. |
@wuestholz yes, your input would be very valuable! We agreed that the goal would be to have two built-in functions: The question is: How to name those two functions? |
@chriseth Great! I think that makes a lot of sense and is consistent with what I suggested above. As I said above, adding a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Now the code is properly waiting for a decision on names.
No description provided.