-
Notifications
You must be signed in to change notification settings - Fork 290
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
Add lazy Wasm compilation #732
Comments
I just wanted to mention that the smoldot light client would hugely benefit from this feature. At initialization, smoldot downloads and compiles the runtime of a chain. The runtime is typically around 1.0 to 1.5 MiB, and this compilation takes around 300ms-400ms on my machine. After initialization, smoldot only executes very small functions from this runtime (typically small getters). In the case of smoldot, the start-up time is extremely important, as the user is waiting before they can interact with the chain. 300ms-400ms isn't that much, but smoldot wants to support connecting to dozens of chains at the same time (so dozens of runtimes), and this compilation time quickly adds up. |
@tomaka Thanks a lot for letting me know about your use case. The register machine Note that Wasm validation will still be eager and thus the 300-400ms smoldot runtime startup time will probably not evaporate entirely. One drawback with lazy Wasm compilation is that the translation process might fail, for example due to overflowing In the |
Is it not possible to disable the validation as well?
It is already not possible for smoldot (or Substrate for that regard) to guarantee ahead of time that execution will succeed. The fact that the Wasm compilation might fail at execution time is just an extra possible reason. Given that there are already many reasons why execution might fail, it really doesn't change much. It's all under the same "the runtime has a bug" umbrella of reasons. Similarly, it would also be ok (for smoldot) if a bad Wasm bytecode (for example an invalid opcode) fails at execution time as well. |
No. While partial Wasm validation is part of the Wasm spec it is also highly controversial as it is a huge safety and security risk and leaders in the Wasm ecosystem say that it was allowed to satisfy some authors of a runtime back in the days and that runtime doesn't even exist anymore today. The only runtime I know of that implements partial Wasm validation is Wasm3. |
I can imagine that there could be risks in executing a single function of Wasm blob that hasn't been fully validated. However here the Wasm blob has been fully validated. Just not by the local machine. Furthermore, since wasmi is an interpreter, I don't really see what the "risk" could be except for the fact that execution could succeed when it normally shouldn't. |
The |
This issue has been mentioned on Polkadot Forum. There might be relevant details there: https://forum.polkadot.network/t/smoldot-updates-threads/4471/12 |
All blockers have been resolved and it is now time to (finally) work on this issue. |
I was able to conduct initial benchmarks in #844. @tomaka If you are able to disable Wasm validation in smoldot speed-ups in compilation performance for your use case are likely 10x, otherwise more like 2x. You can disable Wasm validation if you know that the bytes you operate on is valid Wasm bytecode. |
@tomaka I am mostly done implementing #844. Benchmark results on our CI machines indicate far better speed-ups than on my local machine:
|
Ah great! If I use |
@tomaka There be dragons. Undefined behavior at its finest. |
I see, so this doesn't fit smoldot, but I can use |
Are you able to use multiple threads? In this case I could implement parallel Wasm validation since that would greatly help. |
No |
Due to the discussions in WebAssembly/design#1464 I did not implement partial Wasm validation for However, the reasons against partial Wasm validation are ... valid ... in my opinion and I think it can be dangerous to go there. edit: To clarify: Partial Wasm validation means that Wasm function bodies are only validated on their first use. The problem with this is that is causes invalid Wasm modules to work as long as the invalid parts are unused and thus invalid Wasm modules can become undetected for a while and create a mess. edit2: Partial Wasm validation would yield the same 27x perfomance improvements as unchecked lazy Wasm compilation. |
I don't really understand why you're okay with implementing |
As far as I understand, the main argument against partial validation is:
Indeed, when a runtime upgrade happens, the new runtime would have to be compiled with eager validation in order to check whether it is valid. In the case of the smoldot light client, though, the situation is that we only ever execute the wasm after we have received the guarantee that at least 2/3rds of the validators of the network (who have previously eagerly compiled the wasm) have declared "this wasm is valid". And the smoldot light client is based upon the assumption that at least 2/3rds of the validators are honest, otherwise everything is lost. It seems to 100% fit within the partial validation situation. I'm not ok with "unchecked" validation, because 1) we want to gracefully inform the user if a chain turns out to be broken rather than go into undefined behavior 2) the same instance of smoldot can be used to connect to multiple chains, and if one chain is broken we don't want the other chain connections to be affected. |
Okay let me elaborate on my design thoughts. The goal is to avoid partial Wasm validation while allowing for the fastest possible compilation performance when possible.
In case of the In smoldot I agree that you shouldn't use unchecked Wasm validation since it seems that you do not have this "full control" over the input Wasm blobs. Therefore the middleground solution with lazy compilation & validation would probably make sense for you. |
Follow-up from #729.
Blocked by: #729Currently
wasmi
always validates and translates Wasm towasmi
bytecode for all functions in a Wasm module eagerly.The advantage of this approach is a simpler architecture, slightly less overhead for direct function calls and better performance in case most or all functions are used upon execution.
Benchmarks conducted in the
toywasm
repository showed that Wasm runtimes that employ lazy compilation (and validation) have significantly better startup times which not significantly reduce their execution performance. Also their memory consumption is not inflated either.Despite the performance improvements as indicated by the above benchmarks
wasmi
does not employ lazy compilation. One reason is thatwasmi
bytecode and its translation is fairly simple. With the future shift towards register-machinewasmi
bytecode the compilation overhead is going to be significantly higher compared to the current stack-machine basedwasmi
bytecode architecture and it would make lazy compilation likely very advantageous.This issue tracks progress of lazy compilation.
The text was updated successfully, but these errors were encountered: