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

Stricter contract checks inside Contract.Create and Contract.Update #2030

Closed
roman-khimov opened this issue Oct 27, 2020 · 7 comments · Fixed by #2263
Closed

Stricter contract checks inside Contract.Create and Contract.Update #2030

roman-khimov opened this issue Oct 27, 2020 · 7 comments · Fixed by #2263
Labels
Discussion Initial issue state - proposed but not yet accepted
Milestone

Comments

@roman-khimov
Copy link
Contributor

Summary or problem description
We do almost no checks for contracts and manifests deployed and I think it's a problem. At the moment one can deploy some /dev/urandom contents as a script with almost any garbage in the manifest (the only restriction is ABI hash and group signature correctness) and it will be happily accepted by the chain. I don't think it gives us any benefits, in fact it could be beneficial to provide a bit more guarantees to our users by stricter checks of contracts on their creation/update.

Do you have any solution you want to propose?
We have #1883 for one specific problem already, but I'd like to outline some other things we can check:

It sure will add some overhead to these calls, but TPS metrics are absolutely irrelevant here IMO, because contract creation/update is non-frequent and costly operation. We can do that and this service is being paid for (hi, #2001 also). At the same time we will surely prevent some (not all, of course) errors and tricks that could be done and provide more predictable and safer execution environment.

Neo Version

  • Neo 3

Where in the software does this update applies to?

  • Ledger
  • Syscalls
@roman-khimov roman-khimov added the Discussion Initial issue state - proposed but not yet accepted label Oct 27, 2020
@shargon
Copy link
Member

shargon commented Oct 28, 2020

Thinking about it, I agree with @Qiao-Jin here (#1883 (comment)) , for example we can't check a valid script without executing the script.

PUSHDATA 0x2121212121212121212121212121212121212121212121212121212121212140
JMP -10

It's a valid script and you can't parse if it's valid without execute it.

@roman-khimov
Copy link
Contributor Author

roman-khimov commented Oct 28, 2020

JMP offsets are actually trivial to check without executing them (it can even be done in the same single pass over the bytecode with opcode checks, though two passes make it a bit easier). But it's just one of many things.

@roman-khimov
Copy link
Contributor Author

It's a valid script

I've probably missed the main point. Of course the check would say that this particular script is invalid and it's perfectly fine for me.

We accept some bytecode to store and execute in a public setting, I think it implies some responsibility for it, so if we can with reasonable effort prevent some errors and misbehavior we better do that. And Contract.Create/Update syscalls is just where it all happens, either contract (and manifest) gets accepted or not, that's why it has to be done there.

@shargon
Copy link
Member

shargon commented Oct 28, 2020

Validate only abi and manifest it's ok for me

@roman-khimov
Copy link
Contributor Author

We can start with that, it's easier and it already adds some value.

@igormcoelho
Copy link
Contributor

igormcoelho commented Oct 29, 2020

@shargon the point is having something syntatically correct, at least, which "your eyes" have done already in your example hahaha
But neovm doesn't see it that way. Example, is this script syntatically valid: 010203ab010809bc
Dont take the time to check please, I just put some random bytes. It could be valid or not, I dont know. But if thats invalid, meaning that I'm "using" opcodes that dont exist (yet), this code is certainly flawed for neovm, but it may still execute, give true or false (or FAULT). And in some future, it could be that some nonexisting opcode becomes "existing", and interpretation changes. Its even worse when one reads some prefix like NEF, but content doesnt make any sense (because its random). This simple thing can waste the time if many people that look at the chain.
Chain can be broken in other manners too, but this is quite unnaceptable, because people attaching random bytes as invocation can already cause us huge problems. Validation is different than verification/invocation, and it just takes linear time of the number of bytes in script.

@igormcoelho
Copy link
Contributor

igormcoelho commented Dec 16, 2020

Before I forget... again, I think we should check the integrity of all scripts, even Verification/Witness scripts. If we do that, and we are certain that previous Neo2 scripts will fail on Neo3, then on Neo layer (not NeoVM), we can support some "if" case that allows mapping from previous standard Neo2 script (with CHECKSIG opcode) to equivalent standard Neo3 script. This does not cover all cases, but if it covers 99% of users, that's very good (specially those who may be "left behind" during migration). Again, this "if" would skip execution from Neo3-VM, and manually execute the check (21 + pubkey + ac).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion Initial issue state - proposed but not yet accepted
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants