Skip to content
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

Function states can be corrupted when receiving non expected values #116

Closed
steinerkelvin opened this issue Aug 18, 2022 · 4 comments
Closed
Assignees
Labels
bug Something isn't working discussion

Comments

@steinerkelvin
Copy link
Contributor

steinerkelvin commented Aug 18, 2022

related to #96

Possible solutions:

  1. simple built-in typechecker
  2. monotype contract interface (buffer etc)

FWIW, I think we should allow "sibling" functions to communicate with raw data somehow.

cc @racs4 @developedby @VictorTaelin

@VictorTaelin
Copy link
Contributor

VictorTaelin commented Aug 19, 2022

"sibling" (and any other) functions can just call each other normally. This is just for cross-contract communication

@steinerkelvin
Copy link
Contributor Author

@VictorTaelin
I mean, contracts that are able to communicate freely without the burden of serialization when they are marked as trusted somehow. But it was just an idea from the top of my head, it's probably not worth it.

Also, what do you think about passing the buffers as Braum trees?

@VictorTaelin
Copy link
Contributor

I now believe the best way to solve this issue is to normalize the argument of an IO_CALL operation, and check if it is a flat constructor of numbers. Adding a type-checker only for IO_CALL is not actually feasible, since it deals with arbitrary runtime terms, so we don't have a chance to type-check them at "compile time". We could do that for static calls (i.e., inside top-level runs), but there would be no way to prevent contracts from sending incorrect constructors to each other without performing a deep validation of their arguments.

As such, a monotype contract interface looks more sensible, but what type should we use? A single U120 number is too restrictive. A list of U120 numbers would require normalizing the entire thing, which isn't ideal, and it would still be inconvenient to use. Now, curiously, all contracts that we've written so far already use a quasi monotype: an "Action" sum type where each constructor has numbers. That is convenient, since it allows contracts to be organized as a series of methods. So, that's what we use.

In a future, we could add some form of TRUSTED_CALL operation, allowing contracts to pass arbitrary data to each other.

Note that it is still possible to corrupt a contract's state if it calls another contract that returns an unexpected type. Kindelia does not perform any kind of checking on the return of IO_CALL, since it assumes that a contract and all its dependencies were properly type-checked before deploying. That is on the developer's. The only reason we need this check for the argument of IO_CALL is that anyone, including users and contracts you do not trust, can call your contract. That is not the case of the return value of IO_CALL, since you're the one performing the IO, thus you must only call contracts you trust.

In a future, we could also add some form of runtime type-checking to allow a contract to call an untrusted contract safely, but that isn't an important feature for now.

@steinerkelvin
Copy link
Contributor Author

moved to #208

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working discussion
Projects
None yet
Development

No branches or pull requests

2 participants